/* The copyright in this software is being made available under the BSD
 * License, included below. This software may be subject to other third party
 * and contributor rights, including patent rights, and no such rights are
 * granted under this license.
 *
 * Copyright (c) 2010-2015, ITU/ISO/IEC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  * Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
 *    be used to endorse or promote products derived from this software without
 *    specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

/** \file     TComAdaptiveLoopFilter.cpp
    \brief    adaptive loop filter class
*/

#include "TComAdaptiveLoopFilter.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>

// ====================================================================================================================
// Tables
// ====================================================================================================================
#if ALF_HM3_REFACTOR
#if JVET_C0038_GALF
const Int TComAdaptiveLoopFilter:: m_ALFfilterCoeffFixed[m_NO_FILTERS*JVET_C0038_NO_PREV_FILTERS][21]=
{
  {0, -6, 3, -6, -8, -2, 7, 0, -5, -10, -1, 28, 64, 36, 4, -2, -1, 7, 15, 68, 130},
  {-6, -5, 6, -4, -5, 1, 10, 4, 3, -7, 4, 24, 53, 34, 11, 2, -9, 8, 20, 61, 102},
  {-8, -10, 13, -4, -13, 12, 19, 14, 0, -11, 15, 24, 38, 31, 20, 7, -9, 19, 27, 42, 60},
  {4, 8, -21, 11, 0, -18, -1, -21, -1, 9, -14, 32, 83, 37, -12, 12, 8, -28, -3, 86, 170},
  {-13, -6, 19, 0, -7, 16, 16, 19, 14, -8, 17, 16, 23, 25, 25, 18, -11, 25, 25, 27, 32},
  {-17, 1, 17, 13, 5, 13, 9, 10, 40, -3, 19, 15, 13, 14, 17, 37, -14, 18, 18, 21, 20},
  {13, -7, -1, -1, 22, -24, -2, -32, 28, -5, -26, 7, 88, 9, -34, 2, 18, -3, -5, 94, 230},
  {-2, -11, 21, -10, -19, 8, 17, 14, -15, -19, 7, 19, 44, 34, 18, -1, -3, 29, 28, 52, 90},
  {-12, -9, 9, -13, 0, 10, 19, 17, -3, -12, 13, 20, 46, 31, 19, -9, -19, 14, 28, 52, 110},
  {-5, 0, 2, -9, 8, -5, -8, -9, 28, -3, -4, 12, 58, 46, 7, -7, -8, -1, 2, 71, 162},
  {-23, -9, 23, -15, -6, 20, 27, 28, -5, -11, 23, 21, 30, 32, 33, -4, -34, 31, 36, 36, 46},
  {-27, -8, 28, -10, -2, 25, 25, 31, 3, -13, 29, 17, 19, 30, 37, 2, -34, 33, 37, 25, 18},
  {-72, 20, 38, 2, 25, 19, 28, 31, 50, 6, 23, 0, 3, 12, 38, 18, -84, 54, 33, 8, 8},
  {-7, 3, 12, 3, -4, -10, -2, -13, 5, 2, -8, 17, 64, 28, -3, 4, -6, 4, 9, 81, 154},
  {-5, -5, 12, -5, 2, 1, -9, 0, 3, -8, 3, 1, 55, 12, 4, -3, -5, 14, -12, 71, 260},
  {-7, 0, 7, -2, -5, -7, 8, 0, 3, -5, 0, 20, 56, 29, 7, 4, -8, 6, 21, 67, 124},
  {2, 1, -8, -1, -3, -14, -1, -11, 0, 0, -12, 30, 80, 38, -10, 3, 2, -11, 4, 83, 168},
  {-1, -5, 5, -8, 0, -4, -2, 2, -3, -7, -5, 11, 65, 27, 7, -9, -2, 4, 8, 77, 192},
  {-3, -6, 6, -11, -5, 2, 3, 5, -3, -6, 2, 19, 61, 41, 16, -7, -6, 0, 15, 73, 120},
  {-3, -8, 12, -14, -8, 5, 2, 13, -5, -8, 4, 15, 53, 39, 25, -8, -6, 5, 21, 66, 112},
  {-1, -12, 11, -17, -19, 10, 15, 21, -15, -18, 10, 25, 52, 36, 26, -11, -6, 20, 27, 59, 86},
  {-6, -11, 5, -9, -15, 14, 11, 17, 10, -15, 17, 28, 41, 37, 22, 7, -10, 10, 25, 49, 58},
  {-1, 1, 5, 5, 4, -16, -10, -25, 10, 2, -19, 11, 86, 19, -26, 7, 1, 4, -11, 93, 232},
  {-2, -8, 10, -2, -11, 10, -1, 3, -14, -6, 8, -3, 49, 22, 21, -2, -1, 5, 0, 80, 196},
  {-6, -12, 11, -18, -14, 15, 14, 25, -2, -16, 17, 24, 41, 37, 32, -6, -12, 15, 28, 51, 64},
  {-1, -5, 9, -15, -7, -3, 9, 14, -17, -13, -2, 16, 59, 34, 22, -18, -4, 13, 23, 71, 142},
  {-2, -4, 10, -6, 4, -3, -14, -3, 4, -5, -3, -5, 61, 10, 1, -6, -2, 10, -15, 74, 300},
  {-8, -2, 1, -30, 8, 4, 3, 28, 22, -6, 8, 18, 44, 51, 38, -19, -17, -1, 18, 56, 80},
  {-44, -26, 72, -33, -17, 46, 14, 65, -21, -20, 45, 9, 25, 17, 65, -20, -64, 89, 13, 24, 34},
  {-1, -6, 8, -4, 0, 8, -4, 9, 0, -8, 12, -8, 1, -7, 14, -3, -3, 16, -17, 16, 466},
  {-4, -2, 16, -6, -3, 2, -16, -17, 10, 0, 0, -7, 46, 40, -3, -6, -4, 11, -22, 79, 284},
  {-1, -3, 7, -18, 6, 8, -28, -12, 25, -1, 6, -2, 52, 73, 15, -16, -4, -1, -23, 71, 204},
  {-4, -1, 15, 2, 3, -2, -34, -13, 3, 0, -6, -2, 72, 19, -10, 1, -3, 14, -37, 84, 310},
  {-3, 1, 12, 0, 4, -13, -13, -17, 4, 4, -15, -5, 72, 17, -12, 0, -2, 3, -15, 97, 274},
  {2, 2, -3, -3, -2, -16, -1, -13, -5, 1, -18, 25, 72, 47, -3, -5, 3, -12, 11, 86, 176},
  {-2, 3, 7, 1, 1, -17, -9, -20, -1, 5, -20, 12, 70, 39, -13, -1, 0, -1, -6, 89, 238},
  {-2, -3, 7, -13, -2, 2, -16, 6, -1, -4, 1, 5, 50, 57, 24, -13, -4, 2, -6, 69, 194},
  {-1, -2, 5, 3, 2, -3, -7, -16, 3, -1, -6, 2, 33, 20, -11, 1, 0, 7, -17, 52, 384},
  {2, 9, -8, 12, 4, -30, -4, -39, 9, 10, -31, 32, 88, 45, -38, 12, 5, -14, 0, 86, 212},
  {13, 15, -39, 19, 1, -44, 30, -54, 7, 14, -40, 51, 90, 60, -50, 20, 17, -45, 32, 84, 150},
  {6, 2, -10, 1, -9, -18, 10, -20, 0, 3, -17, 34, 73, 51, -15, 4, 8, -20, 19, 79, 150},
  {-3, -2, 11, -1, 4, -5, -14, -11, 4, -1, -6, -10, 56, 8, -7, -2, -3, 12, -21, 71, 352},
  {-2, -3, 7, -2, 0, 4, -9, 2, -2, -4, 3, -3, 14, 9, 5, -4, -3, 12, -16, 26, 444},
  {0, -2, 5, -4, 1, -3, 3, -1, -2, -5, -2, 2, 5, 14, 5, -6, 0, 6, 1, 13, 452},
  {2, -5, 1, -5, -1, 5, 3, 7, 0, -6, 7, 5, -11, 3, 9, -3, 2, 2, 5, -11, 494},
  {-4, -2, 10, 0, -1, 8, -22, -13, 5, 0, 5, -11, 33, 28, -2, 0, -8, 17, -31, 31, 426},
  {-3, -2, 9, -1, 1, 3, -17, -3, 0, -2, 1, -10, 39, 14, 3, -3, -3, 10, -23, 58, 370},
  {-2, 1, -2, 8, -2, 18, 0, -7, -1, -1, 20, -48, 2, 13, 20, 5, -4, 0, -17, 51, 404},
  {-1, -2, 4, 0, 0, 3, -4, -3, 1, -2, 3, -11, 13, 2, 0, -2, -1, 5, -8, 22, 474},
  {-5, 2, 15, 3, 8, -15, -17, -26, 8, 6, -19, -6, 73, 23, -24, 3, -3, 5, -18, 98, 290},
  {-1, 3, 6, 3, 4, -14, -21, -26, -1, 2, -16, 11, 72, 57, -9, -4, 4, -6, -15, 92, 230},
  {2, 10, -1, 0, -1, -33, 1, -25, -4, 12, -35, 36, 74, 62, -15, -5, 6, -24, 22, 91, 166},
  {-4, -2, 13, 3, 3, 1, -20, -15, 4, -1, -2, -15, 47, 14, -10, 0, -5, 16, -28, 66, 382},
  {-4, 6, 10, 9, 7, -24, -23, -37, 11, 8, -30, 31, 80, 48, -39, 10, -2, 5, -17, 80, 254},
  {-1, 10, -4, 13, 6, -33, -4, -45, 9, 12, -37, 37, 85, 54, -44, 13, 3, -14, 3, 88, 210},
  {6, 4, -12, 8, 2, -22, 0, -37, 3, 4, -24, 31, 81, 61, -31, 7, 10, -19, 3, 83, 196},
  {-3, -3, 10, 1, 1, 4, -15, -7, 4, -2, 4, -18, 34, 1, -6, 0, -4, 15, -26, 50, 432},
  {-2, -2, 8, 0, 0, 4, -15, 0, 0, -2, 3, -11, 25, -3, 1, -1, -3, 12, -20, 34, 456},
  {1, -2, 2, -2, 0, 0, 0, 2, -2, -4, 1, 2, -2, 4, 4, -3, 2, 0, 3, 0, 500},
  {-3, -2, 11, 1, 5, -2, -11, -18, 9, 1, -1, -30, 63, -2, -14, 2, -3, 9, -24, 88, 354},
  {-3, -3, 8, 1, 1, 6, -10, -6, 3, -4, 3, -17, 24, 0, 0, -2, -3, 13, -17, 29, 466},
  {-4, -2, 10, 2, 0, 6, -15, -8, 1, -3, 5, -16, 22, 19, -3, -1, -5, 13, -20, 38, 434},
  {-1, -2, 5, 0, 0, 3, -6, -2, 0, -2, 3, -7, 7, 7, -1, -1, -2, 7, -10, 19, 478},
  {-7, 10, 17, 5, 8, -39, -12, -33, 4, 16, -38, 19, 78, 44, -32, 6, 0, -12, 3, 110, 218},
  {-1, -1, 2, 0, 0, 1, -3, 0, 0, -1, 2, -3, 3, 0, 0, 0, -1, 3, -4, 5, 508},
  {-2, -2, 7, 0, -1, 5, -11, 1, 0, -2, 5, -12, 16, -4, 1, 0, -3, 10, -17, 24, 482},
  {-5, 2, 13, 7, 9, -20, -10, -40, 8, 11, -29, 10, 62, 56, -38, 9, 0, -5, -7, 87, 272},
  {-3, 9, 1, 10, 8, -32, -1, -43, 4, 13, -37, 26, 72, 62, -37, 8, 3, -16, 6, 92, 222},
  {-6, -3, 17, 4, 1, 7, -28, -11, 2, 0, 4, -23, 46, 11, -10, 3, -7, 19, -38, 70, 396},
  {-4, -3, 11, 2, 0, 7, -18, -4, 1, -2, 7, -19, 29, -1, -4, 1, -5, 15, -28, 45, 452},
  {-5, -4, 15, 3, 6, -1, -15, -25, 11, 2, -4, -26, 55, 18, -23, 4, -5, 13, -26, 79, 368},
  {-4, -3, 12, 2, 0, 6, -14, -7, 2, -2, 5, -16, 20, 9, -6, 0, -5, 14, -20, 32, 462},
  {-7, 3, 14, 6, 10, -17, -13, -38, 15, 11, -25, -12, 82, 30, -39, 9, -4, 3, -15, 108, 270},
  {-1, -2, 5, 0, -1, 4, -6, 0, 0, -2, 5, -12, 11, -3, 1, -1, -2, 7, -10, 16, 494},
  {-6, -2, 14, 4, 0, 5, -19, -14, 1, -2, 3, -18, 28, 28, -10, -1, -5, 17, -26, 50, 418},
  {-1, -1, 3, 0, 0, 2, -3, 0, 0, -1, 2, -5, 4, -1, 0, 0, -1, 4, -4, 5, 506},
  {-2, -3, 8, 0, 2, 6, -15, -5, 6, -1, 6, -36, 56, -19, -4, 1, -2, 8, -23, 68, 410},
  {0, 0, 1, 0, 0, 0, -1, 0, 0, 0, 1, -1, 0, 0, 0, 0, -1, 1, -1, 1, 512},
  {-3, -2, 7, 1, -1, 4, -8, -1, 0, -2, 4, -9, 8, 2, -1, 0, -4, 9, -10, 14, 496},
  {-4, -4, 11, 1, -2, 10, -13, -4, 0, -1, 8, -25, 21, 3, -3, 1, -6, 12, -15, 30, 472},
  {-2, -5, 15, -24, -4, 18, -15, -27, 41, 1, 9, -4, 43, 81, 28, -15, -4, -4, -22, 65, 162},
  {-2, -1, 0, -9, -5, -5, 8, 5, 19, -10, -3, 21, 49, 37, 19, 15, -9, 0, 16, 58, 106},
  {-7, -5, 12, -9, -7, 10, 8, 6, 38, -14, 9, 10, 34, 33, 26, 28, -12, 8, 8, 42, 76},
  {-17, -7, 19, 8, 2, 22, 1, -1, 71, -21, 18, 11, 15, 12, 20, 55, -17, 15, -2, 28, 48},
  {1, -2, 4, -4, -1, -6, -4, -16, 15, -3, -10, 18, 66, 44, -1, 13, 1, -11, -5, 75, 164},
  {-13, -10, 13, 1, -6, 21, 7, 14, 40, -18, 18, 14, 27, 29, 15, 31, -16, 17, 8, 36, 56},
  {-19, -8, 20, 17, -5, 26, -1, 1, 82, -24, 22, 10, 9, 3, 9, 77, -14, 18, -8, 21, 40},
  {-18, -9, 14, 18, -8, 22, 2, 7, 78, -25, 21, 13, 13, 2, 15, 70, -15, 19, -1, 19, 38},
  {2, -7, 4, 8, 3, -15, -3, -29, 20, -8, -6, 14, 83, 23, -30, 20, 8, -6, -11, 83, 206},
  {-8, -6, 4, -2, -8, 10, 10, 11, 36, -19, 12, 17, 33, 27, 25, 33, -16, 12, 15, 39, 62},
  {-11, -4, 6, -19, 1, 9, 19, 24, -1, -8, 6, 15, 42, 45, 28, -3, -21, 13, 20, 45, 100},
  {-34, -2, 34, -22, -2, 18, 28, 38, 0, -6, 13, 6, 27, 39, 42, 6, -49, 45, 25, 29, 42},
  {-54, 2, 61, -19, 5, 35, 21, 39, 27, -14, 23, -14, 3, 24, 48, 27, -68, 65, 25, 14, 12},
  {-2, -4, 10, -8, 4, 4, -7, -18, 27, -3, 2, -11, 46, 46, 18, 1, -2, -3, -13, 60, 218},
  {-2, 0, 4, -8, -4, -5, 6, 2, 24, -8, -2, 11, 48, 38, 19, 17, -8, -2, 13, 58, 110},
  {-8, 6, -2, -6, 16, 11, -18, -21, 107, 2, 4, -13, 12, 60, 45, 26, -20, -20, -17, 44, 96},
  {0, 1, 6, -12, 1, -8, -7, -7, 8, 3, -14, 4, 64, 42, 13, -1, -1, -8, -7, 77, 204},
  {1, 0, 1, -16, -2, -5, 6, 7, 12, -3, -8, 13, 49, 48, 29, 8, -7, -10, 14, 62, 114},
  {-2, -5, 2, -14, -5, 8, 10, 12, 40, -17, 9, 16, 32, 34, 31, 31, -14, 1, 16, 42, 58},
  {0, 1, 10, -13, -1, -7, -7, -10, 9, 4, -14, 2, 60, 49, 13, 0, -1, -8, -5, 80, 188},
  {2, -3, 5, -15, -2, 0, -2, -11, 18, 2, -6, 7, 56, 53, 12, 4, -3, -12, -2, 71, 164},
  {-1, 0, 11, -5, -1, -10, -9, -24, 14, 5, -12, 1, 73, 36, -10, 8, -1, -3, -15, 85, 228},
  {-1, -2, 0, -19, -4, 1, 12, 16, 33, -13, 3, 16, 34, 43, 33, 23, -14, -4, 20, 47, 64},
  {-4, -1, 3, -18, 0, 4, 8, 2, 63, -19, 6, 18, 25, 33, 24, 58, -16, -11, 7, 43, 62},
  {-2, 1, -1, -29, 6, -7, 17, 29, -5, 0, -12, 16, 48, 53, 38, -8, -15, 1, 18, 57, 102},
  {-26, -1, 26, -36, -2, 18, 27, 54, 11, -15, 17, 6, 21, 38, 52, 13, -52, 50, 17, 27, 22},
  {0, -4, 11, -11, 5, 0, -4, -5, 14, -7, 5, -15, 27, 20, 20, 2, -4, 6, -19, 47, 336},
  {-5, 5, -11, -19, 0, 6, 6, 6, 93, -14, 13, 16, 18, 33, 34, 42, -25, -4, 9, 31, 44},
  {-1, -3, 20, -23, 3, 3, -13, -17, 35, 3, -3, -13, 39, 69, 42, 9, -9, -19, -8, 68, 148},
  {-4, -2, 11, -5, -3, 20, -5, -68, 41, 1, 21, -10, -1, 107, 28, -13, -5, 4, -50, 53, 272},
  {-4, -3, 12, -20, 2, 30, -15, -54, 66, 4, 19, -25, 3, 110, 55, -9, -7, -12, -41, 55, 180},
  {-5, 0, 9, -28, 12, 13, -19, -17, 93, 4, 3, -10, 19, 75, 51, 5, -18, -15, -12, 49, 94},
  {-3, 0, 16, -5, 0, -5, -13, -18, 3, 9, -13, -15, 62, 39, 5, -5, -1, -2, -14, 92, 248},
  {-1, 1, 16, -13, -1, -8, -13, -10, -1, 11, -18, 0, 58, 61, 29, -6, 0, -14, -4, 83, 172},
  {2, -1, 9, -19, 0, 0, -8, -4, 16, 4, -10, -3, 39, 72, 48, 4, -2, -20, -3, 65, 134},
  {2, -4, 12, -17, -3, 7, -7, -20, 19, 3, -1, -11, 26, 90, 57, -4, -2, -14, -15, 61, 154},
  {-1, -2, 10, -2, 0, 2, -18, -14, 0, 1, -1, -10, 54, 37, 3, -4, 0, 3, -22, 65, 310},
  {6, -1, -2, -14, -1, -7, -1, -3, -3, 5, -16, 18, 59, 61, 15, -3, 3, -22, 8, 77, 154},
  {6, -1, 1, -26, -4, -7, 8, 16, 13, 2, -14, 14, 35, 56, 54, 11, -7, -22, 21, 59, 82},
  {3, 10, -13, 14, 4, -33, 2, -47, 14, 11, -32, 31, 92, 50, -51, 17, 5, -18, 7, 88, 204},
  {2, -1, 15, -22, -1, -6, -6, 1, 5, 9, -16, 2, 43, 64, 52, 4, -4, -23, 7, 68, 126},
  {0, -3, 5, -1, 0, 5, -5, -11, -2, -1, 4, -15, 16, 44, 15, -5, -2, 5, -14, 32, 378},
  {0, -5, 12, -10, 4, 2, -10, -10, 0, -1, -2, -20, 44, 61, 31, -11, 2, -2, -17, 63, 250},
  {-2, -2, 3, 8, -5, 11, -2, -44, 10, 0, 11, -15, 14, 78, 7, -4, -5, 11, -34, 48, 336},
  {-2, -2, 5, 2, -3, 15, -6, -43, 17, 1, 12, -22, 8, 105, 35, -6, -4, 1, -38, 52, 258},
  {-2, -1, 0, 5, -3, 11, 2, -29, 9, -1, 12, -24, 1, 86, 41, -7, -3, 5, -32, 40, 292},
  {1, -2, 13, -26, 1, 24, -9, -55, 64, 4, 10, -33, -3, 107, 89, 11, -7, -26, -41, 53, 162},
  {-2, -3, 11, 5, -1, 9, -28, -27, -3, 1, 3, -15, 55, 73, 5, -3, -2, 11, -44, 81, 260},
  {-1, -4, 5, 5, 1, 7, -12, -18, -1, -4, 9, -23, 36, 33, 4, -3, -1, 11, -30, 56, 372},
  {-2, -3, 9, 3, -1, 8, -11, -29, -6, -1, 6, -22, 32, 85, 16, -10, 1, 5, -29, 65, 280},
  {-2, 4, 13, -6, 1, -15, -15, -10, -17, 14, -25, 4, 64, 72, 26, -11, 3, -17, 1, 88, 168},
  {6, 1, 10, -21, -1, -16, -9, 11, -16, 14, -30, 14, 53, 74, 51, -12, 3, -23, 13, 73, 122},
  {0, -1, -2, 7, -2, 7, 1, -21, -1, -2, 8, -20, 16, 39, -6, 1, -2, 8, -20, 39, 414},
  {-3, -3, 13, 4, -1, 6, -22, -23, -3, 1, 2, -20, 50, 55, -2, -4, -1, 11, -32, 73, 310},
  {-3, 0, 15, 8, -2, -5, -30, -44, 13, 7, -10, 10, 74, 62, -35, 9, -1, 5, -31, 81, 266},
  {3, 5, -5, 10, -2, -18, -9, -48, 10, 12, -24, 26, 88, 64, -38, 13, 8, -21, -7, 90, 198},
  {-2, -6, 12, -3, -4, 16, -9, -42, 7, 1, 7, -20, 23, 116, 29, -10, 3, -1, -37, 59, 234},
  {0, -3, 4, -1, 1, 3, -4, -2, -2, -2, 4, -12, 13, 8, 9, -4, 1, 2, -8, 17, 464},
  {0, -4, 15, -8, 1, 1, -20, -9, -10, 5, -6, -18, 49, 82, 36, -10, 4, -6, -23, 72, 210},
  {-2, -3, 4, 9, -2, 12, -10, -34, -4, -1, 9, -25, 24, 93, 16, -5, -3, 10, -35, 59, 288},
  {-1, -2, -1, 9, -3, 12, 0, -27, -8, -2, 10, -31, 14, 86, -2, -2, -3, 8, -20, 53, 332},
  {0, -1, -2, 6, -1, 6, 0, -11, -4, -2, 6, -16, 0, 46, -3, 2, -3, 5, -9, 24, 426},
  {-1, -1, -3, 9, -3, 11, 2, -24, -6, -3, 12, -31, 10, 75, -9, 1, -3, 8, -17, 46, 366},
  {-4, 0, 11, 3, 0, 0, -12, -23, 0, 8, -6, -33, 66, 37, -9, -1, -1, 1, -18, 102, 270},
  {0, 0, 0, 2, -2, 3, 0, -5, -1, -1, 5, -10, 5, 11, -3, 1, -1, 2, -5, 12, 486},
  {-4, -4, 8, 10, -3, 10, -10, -32, 0, 2, 9, -38, 42, 56, -16, 1, -4, 13, -31, 84, 326},
  {0, 1, 9, 3, 1, -16, -12, -16, -23, 12, -24, 7, 66, 73, 14, -4, 10, -28, 5, 92, 172},
  {-1, -1, -1, 6, -3, 7, -1, -13, -2, -1, 8, -18, 9, 32, -9, 3, -3, 5, -11, 27, 446},
  {-6, -4, 21, 5, -2, 4, -23, -26, -12, 8, -4, -29, 54, 80, 4, -9, 1, 6, -27, 95, 240},
  {0, 0, 0, 1, -1, 2, 0, -2, 0, -1, 2, -5, 1, 6, -2, 1, -1, 1, -2, 6, 500},
  {-2, -3, 7, 4, -2, 8, -7, -22, 7, 1, 7, -27, 29, 34, -28, 8, -2, 3, -16, 58, 398},
  {-2, -1, 3, 8, -3, 9, -13, -15, -4, -3, 12, -24, 30, 29, -6, 3, -5, 16, -35, 57, 400},
  {0, 0, -3, 5, -4, 5, 5, -16, 1, -1, 10, -20, 9, 29, -14, 4, -1, 2, -8, 27, 452},
  {0, 0, -1, 4, -2, 4, -1, -9, 0, -2, 7, -14, 9, 16, -5, 2, -2, 5, -10, 20, 470},
  {-4, -2, 14, 8, -1, 2, -28, -33, 2, 9, -9, -3, 58, 74, -41, 15, 0, -8, -15, 76, 284},
  {-3, -2, 6, 12, -3, 11, -16, -31, -6, 0, 10, -23, 34, 69, -17, 6, -3, 9, -36, 67, 344},
  {-5, -1, 6, 11, -4, 15, -15, -23, -12, 0, 11, -42, 28, 93, 10, -3, -4, 14, -33, 64, 292},
  {-2, -1, -2, 12, -5, 14, -4, -24, -5, -2, 13, -36, 16, 72, -9, 3, -5, 11, -19, 46, 366},
  {-2, -3, 1, 11, -5, 14, -2, -21, -6, -2, 13, -37, 11, 66, -3, 4, -5, 9, -16, 37, 384},
  {-1, -1, 0, 6, -3, 7, -1, -11, -2, -2, 9, -22, 7, 33, -7, 3, -3, 5, -8, 24, 446},
  {-1, 7, -7, -19, -2, -1, 11, 7, 29, -7, -1, 18, 44, 34, 34, 19, -11, -9, 13, 48, 100},
  {-2, 4, 7, -7, -1, 1, -6, -3, 33, -21, 5, 1, 31, 20, 49, 57, -10, -3, 21, 38, 84},
  {-12, -17, 20, 14, -6, 22, 4, 27, 70, -16, 17, -17, 11, -5, 29, 76, 4, 31, -15, 5, 28},
  {-6, -12, 24, 12, -9, 10, 3, 27, 52, -11, 10, -19, 8, 0, 36, 84, 19, 31, -17, -2, 32},
  {-4, 7, -19, 6, 9, 2, -6, 20, 131, -10, 11, -16, -11, -10, 48, 100, -2, 3, -21, 3, 30},
  {-1, -2, 5, 6, -13, 6, 8, 13, 44, -26, 14, 3, 36, 13, 32, 61, 2, 23, 0, 13, 38},
  {-3, 1, 5, -30, 17, 28, -12, -31, 85, 2, 10, -20, -8, 58, 94, 22, -6, -39, -17, 48, 104},
  {0, -4, 2, -9, 7, -1, 15, 9, 44, -25, 15, -9, 51, 6, 37, 47, 1, 6, 1, 12, 102},
  {-1, 2, 1, -15, -3, 2, 3, 7, 24, -11, 9, 15, 40, 36, 33, 28, -11, -1, 9, 39, 100},
  {-7, -1, -6, 9, -4, 7, 3, 23, 78, -13, 14, -3, 10, 5, 39, 70, 1, 14, -10, 10, 34},
  {-9, -6, 22, -16, -7, 18, -5, 8, 93, -43, 25, -19, -9, -25, 55, 139, 10, 34, -13, -4, 16},
  {-4, -4, 10, -9, -4, 11, -1, 9, 46, -30, 21, 4, 18, 12, 38, 69, -12, 19, 3, 26, 68},
  {-16, 10, 5, -15, -3, 14, 19, 27, 30, -18, 13, 5, 24, 35, 38, 41, -34, 33, 12, 19, 34},
  {-8, 5, 3, -3, -5, 15, 2, 15, 64, -31, 18, 10, 17, 4, 46, 76, -17, 21, -3, 13, 28},
  {-4, -1, 11, -26, 1, 39, 2, -73, 86, 4, 28, -13, -12, 96, 92, -29, -9, -11, -46, 46, 150},
  {-5, 20, -10, -8, 24, 11, -19, -8, 107, 2, -6, -20, -16, 32, 71, 63, -19, -29, -13, 42, 74},
  {-1, 2, 12, -23, 1, 8, -12, -25, 61, 3, -2, 0, 29, 58, 46, 9, -6, -8, -17, 56, 130},
  {-2, 9, -5, -24, 1, -3, 14, 6, 44, 4, -8, 16, 32, 42, 46, 22, -17, -13, 11, 45, 72},
  {-1, 5, 5, -21, 1, -2, -2, -17, 64, 4, -11, 10, 33, 42, 40, 36, -9, -11, -8, 47, 102},
  {-1, 10, -2, -22, 0, 5, 7, -7, 63, -8, -3, 13, 17, 22, 54, 72, -20, -20, 13, 35, 56},
  {-1, 8, 4, -34, -4, 17, 3, -10, 95, -25, 13, 11, -2, 9, 45, 108, -15, -10, -2, 23, 46},
  {1, 2, 6, -20, -1, 0, 5, -16, 24, 2, -11, 12, 48, 52, 39, 13, -5, -18, 0, 59, 128},
  {0, 4, 7, -15, -4, -2, 2, -5, 25, -3, -7, 15, 38, 38, 37, 34, -10, -7, 6, 50, 106},
  {-2, 1, -1, -22, -10, 18, 10, 6, 66, -18, 23, 16, 12, 11, 33, 85, -9, 5, -10, 17, 50},
  {-2, 10, 4, -40, -2, 17, -1, -13, 96, -43, 28, 1, -12, -1, 35, 168, -17, -2, -10, 18, 44},
  {-5, 5, -8, -14, -8, 9, 22, 14, 41, -9, 11, 19, 24, 33, 29, 47, -14, -2, 4, 30, 56},
  {-1, 5, 6, -28, 3, 9, -2, -19, 96, -7, 0, 5, 5, 23, 71, 72, -18, -26, 4, 32, 52},
  {0, 5, 5, -28, 3, 4, 3, -18, 77, 2, -9, 7, 21, 35, 61, 35, -12, -22, -2, 47, 84},
  {-1, 16, -20, -21, 0, 5, -10, 8, 124, -18, 17, 8, 7, 21, 36, 61, -9, 7, -13, 16, 44},
  {-3, -2, 11, -13, -5, 28, 9, -98, 85, -4, 26, -2, -14, 109, 76, -34, -4, 4, -45, 42, 180},
  {-4, -2, 12, -28, 0, 44, -2, -79, 108, 0, 27, -18, -22, 97, 94, -20, -5, -16, -42, 43, 138},
  {-1, 6, 10, -18, -6, 7, 0, -21, 31, -3, -8, 10, 24, 30, 60, 61, -13, -14, 11, 49, 82},
  {0, -3, 9, -3, -1, 6, -8, -36, 18, -1, 6, -8, 31, 82, 28, -11, 0, 3, -27, 60, 222},
  {0, 0, 15, -19, 1, -1, -8, -21, 37, 7, -9, 2, 36, 55, 49, 11, -3, -19, -5, 62, 132},
  {0, 2, 13, -20, 0, -3, -5, -26, 52, 9, -10, 6, 26, 42, 57, 29, -6, -25, 1, 61, 106},
  {2, 8, -1, -24, 0, 2, 6, -22, 60, -1, -7, 18, 17, 30, 69, 58, -13, -28, 10, 39, 66},
  {2, -1, 7, -13, -4, 3, -4, -21, 12, 5, -7, 3, 49, 64, 11, -1, 0, -9, -11, 75, 192},
  {1, 1, 10, -25, 1, 1, 1, -21, 43, 4, -8, 8, 30, 56, 65, 20, -8, -21, -1, 52, 94},
  {2, -7, 13, -9, -3, 8, -6, -41, 31, 2, 3, -11, 40, 81, 37, -10, 2, -1, -29, 59, 190},
  {0, -3, 10, -4, -2, 6, -10, -28, 21, 1, 4, -12, 36, 57, 37, -3, -1, 0, -25, 50, 244},
  {1, -2, 16, -21, 2, -4, -6, -18, 36, 6, -11, -1, 37, 58, 55, 11, -3, -17, -2, 58, 122},
  {-1, -2, 16, -7, -3, 1, -9, -33, 25, 6, -4, -10, 40, 66, 42, 7, -1, -6, -19, 61, 174},
  {0, -2, 19, -17, -2, 4, -13, -32, 45, 6, -5, -4, 32, 70, 54, 8, -2, -11, -14, 54, 132},
  {-1, 0, -1, 8, -5, 11, 4, -71, 45, -4, 14, 2, 8, 90, 38, -16, -5, 13, -36, 40, 244},
  {-1, -3, 1, -2, -4, 23, 9, -84, 71, -2, 20, -6, -12, 106, 78, -13, -4, -1, -41, 32, 178},
  {-1, -3, 5, -25, -1, 36, 5, -99, 122, -1, 27, -16, -34, 106, 103, -2, -3, -11, -40, 16, 144},
  {-2, 0, 11, -66, 10, 41, -25, -72, 200, -1, 32, -38, -29, 93, 108, -13, -2, -4, -51, 8, 112},
  {-4, 2, 22, -13, -3, -8, -9, -21, 20, 12, -15, -9, 53, 45, 20, 4, -3, -8, -4, 83, 184},
  {0, -5, 12, -6, 0, 3, -8, -25, 14, -2, 4, -9, 30, 50, 16, -11, 4, 0, -20, 65, 288},
  {0, -8, 21, -15, 0, 8, -10, -32, 23, 2, 3, -11, 34, 74, 50, -9, 3, -12, -19, 63, 182},
  {8, 1, 3, -25, 6, -13, 4, -9, 25, 7, -16, 15, 39, 57, 53, 7, -6, -24, 11, 57, 112},
  {2, -3, 6, 0, -3, 0, -4, -28, 4, 1, 4, -6, 30, 71, -10, 1, 1, 1, -19, 55, 306},
  {12, -4, -7, -4, -3, -17, 8, -25, 5, 13, -27, 30, 74, 48, 11, 12, 8, -33, 2, 79, 148},
  {-1, 1, -2, 10, -5, 11, 0, -46, 12, -2, 9, -18, 19, 105, 30, -10, -2, 9, -30, 48, 236},
  {1, 0, -3, 8, -1, 4, 3, -28, 4, -4, 9, -16, 13, 65, 10, -5, -2, 8, -18, 33, 350},
  {-1, -3, 13, -5, -3, 6, -9, -28, 17, 1, 4, -15, 29, 69, 41, -9, 3, -1, -25, 56, 232},
  {-2, -4, 17, -12, -1, 6, -12, -25, 31, 8, -2, -15, 26, 84, 61, -4, 0, -11, -17, 59, 138},
  {1, -7, 21, -18, 4, -7, -9, -22, 39, 14, -11, -10, 30, 66, 80, 23, 0, -28, -2, 45, 94},
  {-2, -5, 12, -8, 1, 15, 9, -88, 107, -5, 15, -12, -12, 102, 83, -28, -4, 10, -33, 20, 158},
  {0, 2, -9, 15, -2, 5, 5, -52, 19, -3, 10, -5, 7, 87, 20, -4, -4, 9, -29, 43, 284},
  {0, -1, -3, 11, -4, 11, 7, -69, 46, -4, 15, -9, -3, 112, 50, -11, -4, 8, -31, 34, 202},
  {-2, -6, 17, -31, 1, 23, 0, -95, 173, -6, 21, -14, -18, 109, 74, -54, -2, 28, -37, 11, 128},
  {-1, 0, 2, 9, -4, 4, -6, -33, 1, -2, 15, -32, 45, 75, 6, 2, -3, 13, -32, 56, 282},
  {-5, -2, 22, -5, -4, -3, -13, -16, -2, 13, -6, -28, 55, 59, 19, -3, 0, -4, -14, 88, 210},
  {0, 0, 0, 2, 1, 0, 0, -5, -2, -2, 2, -5, 4, 17, 3, -2, 0, 4, -4, 8, 470},
  {-3, -4, 15, 1, -3, -3, -8, -20, -13, 17, -9, -24, 50, 68, 27, -9, 2, -13, -9, 98, 192},
  {0, 2, -7, 11, -2, 3, 0, -20, -6, -1, 5, -8, 9, 61, -13, 6, -3, 7, -20, 38, 388},
  {0, -1, -3, 12, -1, 5, -2, -29, 1, -3, 8, -21, 13, 86, -1, -3, -5, 15, -22, 54, 306},
  {0, 1, -3, 4, -2, 2, 3, -9, -5, -1, 5, -11, 3, 40, -3, 2, -1, 2, -5, 16, 436},
  {0, 2, -3, 8, -5, 3, 0, -21, 0, 1, 8, -9, 9, 47, -21, 8, -2, 2, -16, 36, 418},
  {0, 1, -4, 12, -5, 5, -3, -29, -2, 0, 11, -16, 21, 68, -20, 9, -3, 7, -29, 59, 348},
  {0, -6, 7, 3, -5, 8, -3, -26, 0, 3, 8, -30, 35, 59, -21, 5, 1, -1, -21, 83, 314},
  {0, 0, 0, 12, -7, 5, -4, -39, 1, 1, 11, -10, 19, 87, -30, 9, -3, 6, -29, 56, 342},
  {-1, -4, 5, 12, -3, 10, -10, -32, 5, -2, 9, -29, 16, 107, 23, -5, -3, 15, -28, 57, 228},
  {1, -4, 3, 11, -6, 9, -3, -40, 15, -3, 12, -24, 4, 120, 38, -4, -1, 9, -27, 41, 210},
  {1, 0, -6, 11, -2, 4, 2, -20, -7, -3, 9, -19, 6, 80, -7, 6, -2, 5, -14, 33, 358},
  {-4, -5, 10, 9, -2, 13, -9, -39, 19, -1, 11, -31, 6, 112, 56, -6, -1, 8, -30, 43, 194},
  {0, 1, -6, 13, -3, 6, 5, -26, -6, -4, 11, -23, 3, 106, 13, 1, -4, 9, -18, 31, 294},
  {0, 2, -8, 11, -2, 3, 3, -21, 0, -1, 9, -17, 7, 60, -11, 3, -4, 7, -15, 41, 378},
  {1, 3, -6, 5, -4, 2, 9, -10, -11, -1, 9, -17, -2, 65, -12, 5, -1, -1, -5, 26, 402},
  {0, -5, 6, -7, 0, -2, -2, -4, -4, -14, -3, 14, 49, 24, 5, 5, -1, 8, 17, 79, 182},
  {-5, -6, 11, -11, -12, 8, 7, 5, -3, -15, 14, 23, 35, 28, 17, 23, -14, 33, 32, 50, 72},
  {-5, -8, 12, -12, -18, 15, 14, 8, -2, -15, 20, 24, 33, 24, 16, 28, -6, 33, 29, 38, 56},
  {-7, -6, 23, -7, -22, 13, 4, 2, -4, -11, 9, 18, 31, 23, 7, 28, 2, 35, 24, 53, 82},
  {-2, 1, 3, -4, -3, -10, -2, -8, 0, -13, 0, 25, 56, 28, 2, 9, -6, 6, 28, 79, 134},
  {-4, -1, 9, -4, -7, -4, 2, -4, -2, -10, 4, 21, 49, 24, 3, 14, -7, 14, 26, 68, 130},
  {1, 1, 0, 9, 11, -26, -14, -28, 11, -3, -23, 29, 88, 30, -34, 13, 22, -11, -10, 94, 192},
  {-2, -6, 11, -6, -17, 8, 10, 3, -21, -18, 5, 17, 38, 26, 14, 7, -1, 30, 30, 65, 126},
  {-16, -10, 23, -8, -23, 36, 13, 11, 20, -3, 18, 17, 3, 8, 1, 76, 12, 52, 12, 13, 2},
  {0, -12, 6, -27, -4, 12, 16, 20, -6, -22, 16, 24, 41, 28, 22, 0, -24, 30, 35, 54, 94},
  {-24, -9, 41, -25, -6, 28, 11, 24, 0, -17, 28, 16, 15, 22, 35, 23, -43, 45, 38, 33, 42},
  {-35, 6, 35, -22, -5, 32, 18, 25, 21, -15, 30, 11, 6, 15, 19, 47, -56, 65, 29, 21, 18},
  {-2, -3, 11, -2, -4, 9, -6, 1, -8, -9, 3, -11, 18, 1, 5, 16, -3, 13, -4, 94, 274},
  {-4, -4, 14, -13, 0, 13, -11, -10, -3, -4, 2, 3, 27, 40, 40, 22, -16, 4, 21, 69, 132},
  {13, -23, 8, -27, 34, -5, 18, -22, 44, -27, -7, -33, 53, -17, -7, -3, 20, 10, 14, 78, 270},
  {-7, -3, 31, -6, 9, 2, -8, -34, 44, -5, 19, -4, 30, 4, 11, 61, 2, 16, 17, 28, 98},
  {-1, 1, 8, -3, 0, -8, -10, -7, -11, -10, -11, 13, 54, 33, 12, 1, -3, 5, 20, 90, 166},
  {0, -1, 5, -9, -5, -6, -2, 3, -14, -14, 2, 25, 49, 33, 20, 8, -13, 11, 34, 73, 114},
  {1, -9, 6, -19, -17, 13, 8, 15, -16, -24, 19, 27, 40, 33, 25, 13, -15, 34, 33, 54, 70},
  {1, 0, -4, -1, 1, -11, -1, -10, -8, -7, -12, 26, 67, 37, -1, 6, -1, -1, 13, 83, 158},
  {-3, -1, -1, 14, -6, 16, -3, -15, -3, 1, 18, -32, -21, 1, 36, 27, 3, -5, -14, 104, 280},
  {-2, -1, 3, 4, 5, -6, -6, -13, 0, -3, -17, -1, 60, 13, -15, 5, 1, 11, -10, 96, 264},
  {0, -15, 27, -25, -36, 30, 8, 29, -28, -36, 33, 16, 27, 22, 41, -2, -15, 70, 36, 46, 56},
  {1, -8, 10, -32, -12, 13, 10, 32, -17, -28, 27, 27, 33, 31, 41, 8, -31, 37, 40, 47, 54},
  {-2, -3, 9, -11, 0, 1, -5, 8, -12, -17, 1, 12, 45, 27, 22, -5, -11, 14, 26, 76, 162},
  {-2, -2, 6, -2, -4, 4, -1, 0, -6, -8, 6, -10, 20, -1, 12, -1, 0, 15, -22, 81, 342},
  {-5, -16, 36, -48, -32, 42, 5, 49, -16, -37, 49, 22, 8, 21, 54, 16, -27, 49, 39, 37, 20},
  {2, -9, 10, -12, 2, 7, -1, 6, 5, -14, 19, -18, 5, -13, 15, -2, -2, 28, -38, 50, 432},
  {-2, -6, 18, -7, -16, 2, 10, 9, -26, -25, -2, 12, 38, 27, 20, -20, -7, 44, 42, 79, 132},
  {0, -11, 22, -32, 6, 11, -12, 1, 19, -18, 9, 4, 23, 32, 32, 22, -17, 16, 34, 65, 100},
  {-4, -1, 9, -3, 0, 17, -13, -18, -11, 8, -1, -12, 14, 40, 48, 24, -14, -23, 1, 95, 200},
  {-3, 1, 13, -5, 1, -9, -8, -8, -2, 2, -16, 2, 48, 14, -2, 8, -5, -6, 12, 107, 224},
  {-3, -1, 9, 5, 4, -2, -17, -18, -3, 1, -15, -2, 50, 27, 1, -2, 0, -2, -11, 101, 268},
  {-3, 2, 9, 3, 4, -14, -8, -18, -10, 0, -22, 12, 54, 35, 9, -4, -1, -11, 21, 101, 194},
  {2, -2, 9, -7, 0, -11, -6, -7, -20, -2, -14, 11, 49, 41, 33, 1, -3, -11, 28, 86, 158},
  {-2, 6, -1, 9, 7, -22, -8, -31, 6, 5, -28, 21, 79, 36, -30, 7, 2, -6, 0, 88, 236},
  {3, 1, -3, 0, 3, -16, -1, -12, -17, -1, -19, 26, 62, 44, 11, 6, -1, -18, 25, 84, 158},
  {-1, 0, 9, -4, 0, -9, -7, -6, -17, -8, -12, 10, 43, 40, 30, -7, -7, 1, 33, 92, 152},
  {0, 5, -6, 14, 7, -27, -3, -41, 5, 9, -31, 25, 84, 49, -36, 20, 5, -18, 4, 89, 204},
  {-2, -3, 7, 1, 3, 0, 0, -17, 1, 3, -10, -22, 45, 5, -1, -2, -1, 3, -16, 97, 330},
  {-1, -3, 5, -2, 0, 5, -2, -1, -4, -6, 5, -8, 3, 7, 13, -3, -3, 11, -9, 27, 444},
  {-1, -4, 6, 0, 2, 5, -2, -9, -3, -2, -5, -18, 21, 14, 10, -7, -2, 6, -4, 69, 360},
  {-1, -3, -2, 8, -2, 20, -10, -19, -15, 4, 0, -10, 13, 26, 30, 14, -8, -6, -27, 86, 316},
  {1, -4, 8, -14, 13, 10, -5, -16, -33, 7, -9, -11, 17, 42, 72, 69, -37, -34, 37, 80, 126},
  {-2, -3, 11, 1, 4, -7, 0, -19, 0, 5, -20, -10, 46, 14, -5, 0, -2, -5, 0, 116, 264},
  {-4, -3, 7, -2, 3, 9, -8, -9, -4, -5, -1, -12, 16, 30, 23, -5, -6, 5, -8, 86, 288},
  {-1, -2, -2, 11, -4, 9, 5, -16, -2, -2, 22, -38, -9, 3, 34, 12, -2, 0, -16, 85, 338},
  {-3, -1, 20, -5, 4, -12, -7, -16, -11, 11, -30, 4, 41, 32, 18, 2, -1, -24, 20, 117, 194},
  {-4, -3, 11, 5, 5, -5, -6, -24, 2, 8, -20, -7, 43, 22, -10, 1, 0, -9, -5, 103, 298},
  {-4, 4, 5, 12, 6, -15, -9, -28, -16, 4, -24, 10, 52, 46, 12, -1, 5, -23, 12, 101, 214},
  {-1, -2, 5, 7, 2, -5, -10, -14, -36, 7, -18, 6, 45, 55, 44, 1, 2, -37, 24, 95, 172},
  {-3, -3, 5, 6, 1, 6, -5, -17, 0, 4, -7, -23, 31, 20, -10, 1, -2, 0, -12, 93, 342},
  {-5, 3, 10, 8, 5, -13, -14, -24, -6, 7, -24, 8, 54, 39, -3, 1, 0, -14, 5, 97, 244},
  {-5, 4, 11, 10, 7, -16, -23, -36, 10, 12, -35, 21, 76, 44, -41, 13, 0, -6, -3, 81, 264},
  {1, 15, -18, 19, 9, -48, 15, -56, 9, 15, -47, 52, 86, 62, -49, 19, 10, -34, 26, 76, 188},
  {-2, -5, 12, -1, 2, 4, -13, -6, 3, 3, 0, -22, 37, -3, -5, 1, -4, 13, -38, 92, 376},
  {-3, -5, 14, 1, 6, -8, -4, -20, 6, 9, -14, -19, 55, 3, -13, 4, -1, -5, -18, 117, 302},
  {-1, -1, 2, 1, -1, 5, -2, -3, -1, -2, 4, -13, 6, 3, 5, -3, -2, 6, -10, 37, 452},
  {-1, -2, 3, 1, 0, 2, 1, -5, -1, -2, 3, -11, 7, 2, 4, -2, -1, 2, -4, 26, 468},
  {-1, -3, 2, 5, -1, 8, -3, -10, -5, 2, -2, -17, 18, 7, 9, -1, -2, 0, -15, 75, 380},
  {-4, -4, 7, 10, 0, 4, -6, -19, -7, 4, -6, -19, 23, 25, 10, -2, -2, -1, -15, 104, 308},
  {-5, -4, 8, 12, -2, 15, -23, -15, -11, 9, -8, -21, 36, 27, 8, 7, -6, 3, -27, 99, 308},
  {-3, -3, 4, 4, -1, 7, 1, -13, 0, 0, 3, -26, 9, 16, 6, -5, -4, 9, -13, 70, 390},
  {-6, 0, 19, 6, 7, -21, -8, -33, -5, 16, -41, 17, 55, 45, -7, 1, -2, -26, 33, 111, 190},
  {-1, -2, 3, 0, -1, 4, -3, -1, 0, -1, 4, -9, 6, -1, 1, 0, -2, 4, -7, 16, 492},
  {-2, -4, 7, 3, 0, 8, -11, -8, 1, 1, 4, -26, 29, 3, -3, 1, -4, 13, -36, 82, 396},
  {-4, 0, 3, 15, 3, -4, -4, -25, -12, 11, -15, -13, 39, 27, 1, 8, 2, -19, -13, 111, 290},
  {0, -2, 2, 1, -1, 4, -2, -4, 0, -1, 6, -17, 14, -1, 1, 1, -1, 4, -14, 37, 458},
  {-6, -6, 13, 9, 2, 12, -22, -18, 0, 2, -5, -23, 37, 25, -9, 1, -3, 10, -34, 103, 336},
  {-3, 6, -3, 17, 7, -25, 2, -42, -3, 11, -35, 26, 63, 55, -30, 13, 8, -35, 22, 85, 234},
  {-3, -5, 8, 8, -1, 11, -7, -22, -1, 5, -2, -27, 32, 23, -15, 9, 1, -12, -3, 61, 392},
  {0, -1, 2, 0, 0, 2, -2, 0, 0, -1, 2, -4, 2, 0, 1, 0, -1, 2, -5, 9, 500},
  {0, -1, 1, 0, 0, 2, -1, 0, 0, 0, 1, -3, 2, -1, 1, 0, -1, 1, -2, 4, 506},
  {-5, -6, 15, 9, 9, -8, -3, -37, 6, 17, -35, -6, 50, 40, -36, 12, 4, -28, 13, 104, 282},
  {0, -2, 3, 0, -1, 5, -5, -2, 1, -1, 6, -15, 15, -4, 0, 0, -3, 9, -21, 38, 466},
  {-1, -2, 3, 2, -2, 6, -4, -7, 1, -1, 8, -23, 20, -1, 0, 0, -3, 11, -29, 61, 434},
  {-3, -5, 7, 6, -2, 10, -6, -16, 1, 1, 5, -28, 20, 13, 0, 0, -3, 8, -24, 77, 390},
  {-3, -5, 8, 4, -2, 12, -10, -9, 0, 3, 4, -29, 19, 9, 0, 1, -7, 11, -15, 55, 420},
  {-2, -4, 7, 1, -1, 8, -6, -6, 1, 0, 7, -22, 15, 0, 3, -1, -4, 7, -9, 32, 460},
  {-2, -5, 9, 0, 6, -5, 3, -20, 10, 6, -5, -28, 48, -6, -16, 7, 0, 0, -29, 103, 360},
  {2, -5, 3, -6, -7, 8, 0, -5, -18, -18, 4, 22, 36, 27, 14, 31, 0, 19, 22, 69, 116},
  {0, -7, 7, -13, -42, 29, 25, 12, -23, -11, 8, 28, 25, 15, 6, 55, 21, 61, 11, 28, 42},
  {-3, -3, 12, -15, -18, 9, 14, -5, 8, 0, 2, 16, 28, 7, 6, 65, 13, 47, 8, 32, 66},
  {1, -6, 4, -6, -11, 8, 11, -2, -21, -23, 4, 26, 32, 18, 11, 39, 6, 32, 27, 60, 92},
  {-1, 2, 4, 2, 5, -15, -8, -23, 4, -9, -16, 29, 62, 29, -14, 19, 19, 0, -4, 95, 152},
  {-1, -4, 15, -14, -51, 30, 22, 19, -37, -15, 6, 25, 14, 24, 18, 40, 19, 83, 19, 30, 28},
  {-5, -7, 21, -22, -51, 38, 18, 17, -2, 20, -5, 24, 2, 6, -10, 94, 37, 76, -8, 12, 2},
  {-9, -3, 11, -1, -32, 24, 8, -8, 53, 24, -12, 13, 8, -6, -19, 114, 24, 75, -17, 4, 10},
  {-14, 13, 17, 5, 1, 5, -3, -25, 36, 10, -40, 14, 4, 1, -15, 141, 25, 34, -17, 43, 42},
  {0, -4, 3, -1, -6, 9, 12, 7, -27, -33, 2, 11, 20, 17, 10, 3, -1, 41, 45, 79, 138},
  {-3, 2, 11, -5, -4, -8, -5, -11, 1, -13, 3, 20, 35, 13, 1, 28, 4, 13, 25, 83, 132},
  {-2, -1, 11, -7, -4, 7, -2, 4, -11, -17, -1, 9, 20, 4, 1, 32, 3, 12, 18, 87, 186},
  {-6, 5, 14, -12, -17, 11, 7, -2, -2, -22, -1, 25, 21, 7, 7, 83, 9, 36, 15, 49, 58},
  {-1, 0, 11, -17, -39, 22, 18, 3, 22, -2, 2, 18, 16, 1, -3, 99, 18, 59, 0, 14, 30},
  {-2, 0, 6, 0, -36, 21, 28, 12, -56, -30, 9, 18, 26, 16, 19, 21, 17, 69, 32, 44, 84},
  {34, -37, 1, -49, 52, -3, 9, -18, 59, -44, -6, -2, 41, -13, -12, 15, 20, 1, 7, 77, 248},
  {3, -5, 3, -5, 23, -17, -2, -11, -3, -34, -13, 13, 53, 21, 0, 4, 2, 26, 26, 90, 164},
  {4, -3, -1, -5, -7, 0, 7, 10, -36, -45, 18, 31, 38, 26, 22, 18, -11, 52, 35, 60, 86},
  {7, -10, 1, -13, -32, 24, 18, 15, -44, -36, 29, 32, 30, 17, 14, 48, 5, 66, 20, 39, 52},
  {2, -3, 10, -17, -31, 24, 11, 13, -32, -53, 39, 35, 17, 8, 8, 77, -3, 67, 30, 37, 34},
  {5, -7, 4, -14, 11, 0, 7, 9, -12, -56, 2, 19, 34, 11, -9, 26, 4, 60, 13, 77, 144},
  {-1, 1, 8, -2, -2, -1, 3, 4, -37, -39, 7, 22, 28, 13, 11, 51, -3, 45, 32, 66, 100},
  {2, -14, 13, -12, -54, 46, 28, 34, -64, -32, 28, 32, 13, 9, 17, 46, 14, 111, 9, 19, 22},
  {-1, -4, 6, 1, 0, 2, 5, 2, -18, -17, -5, 1, 22, 8, 3, 2, -3, 17, 29, 102, 208},
  {2, -6, 17, -27, -51, 44, 19, 22, -40, -53, 50, 37, 11, 0, 1, 91, 5, 82, 17, 26, 18},
  {-2, -2, 11, 2, -1, -5, -1, -3, -19, -21, 0, 14, 30, 13, 4, 9, -5, 24, 38, 94, 152},
  {-1, -3, 12, -6, 0, -4, -3, 2, -12, -9, 1, 4, 19, 6, -5, 27, -7, 5, 20, 107, 206},
  {-2, 0, 5, 2, 0, 6, 5, -2, -25, -18, -8, -1, 18, 9, 5, 27, -6, 9, 33, 109, 180},
  {0, -6, 5, 4, -14, 15, 23, 26, -66, -32, 7, 3, 2, -5, 15, 34, 3, 38, 36, 88, 160},
  {1, -21, 23, -1, -47, 31, 38, 24, -74, -52, 24, 28, 20, 18, 26, -4, 10, 96, 45, 45, 52},
  {0, -4, 1, 3, 17, 2, 11, 0, -17, -39, 4, -20, 3, -19, -14, 62, 9, 17, 10, 99, 262},
  {-8, 4, 49, -37, 46, -38, -29, -7, -2, -30, 4, 40, 7, -22, -78, 216, -26, -41, 122, 68, 36},
  {-2, -4, 7, 5, 15, -8, -3, -5, -18, -17, -21, 3, 33, 21, 5, 3, -1, 9, 29, 114, 182},
  {-1, -3, 7, 4, 15, -9, -3, -1, -22, -31, -9, 2, 28, 20, 21, -4, -2, 27, 33, 97, 174},
  {-3, 0, 6, 7, 12, -12, 3, 4, -42, -38, -6, 10, 27, 20, 28, 12, -8, 36, 44, 95, 122},
  {-1, 2, 2, 10, 6, -12, 3, 16, -67, -59, 15, 22, 25, 13, 34, 39, -10, 66, 34, 77, 82},
  {1, 5, -12, 12, 12, -25, 4, -30, 0, -7, -30, 22, 81, 39, -27, 6, 7, 7, 4, 92, 190},
  {0, 4, -1, 1, 8, -12, 4, 12, -40, -55, 11, 19, 31, 23, 32, 15, -7, 51, 31, 81, 96},
  {-2, -5, 10, 2, 11, -5, -3, -12, -4, -4, -21, -6, 38, 12, -1, -1, -3, -1, 17, 118, 232},
  {-1, -5, 2, 3, 7, 2, 2, -10, -3, -3, -16, -19, 45, 0, -6, 3, 0, 10, -10, 99, 312},
  {-2, -4, 2, 6, 8, 3, 6, -2, -20, -19, -16, -5, 26, 14, 8, -2, -1, 18, 20, 105, 222},
  {-1, -4, 3, 2, 3, 6, 1, 0, -12, -11, -2, -13, 12, 7, 14, -6, -2, 20, -8, 84, 326},
  {-1, -4, -2, 9, 0, 12, 14, 6, -41, -28, 0, -17, 8, 10, 25, 12, 0, 23, 24, 108, 196},
  {-1, -3, 0, 5, 3, 6, 4, 5, -21, -17, -2, -12, 8, 7, 16, 5, 0, 21, 1, 77, 308},
  {-1, 1, 14, -7, 18, -16, 4, 14, -51, -43, 0, 1, 21, 1, 23, 75, -2, 28, 35, 84, 114},
  {-2, -1, 1, 6, -12, 24, 9, 2, -43, -4, -7, -20, -1, 16, 36, 31, -5, 0, 21, 117, 176},
  {-1, -3, -2, 7, -2, 32, 15, -24, -63, 6, 0, -22, -15, 1, 56, 128, -45, -28, 60, 90, 132},
  {-1, -5, 9, 0, -2, 6, 5, -9, -10, 9, -21, -9, 25, 6, -6, 15, 0, -18, 10, 134, 236},
  {-1, -7, 10, 0, 4, 0, 5, -16, 3, 9, -23, -13, 33, 6, -11, 4, 0, -13, 3, 130, 266},
  {-3, -5, 7, 7, 14, -7, 4, -20, -9, -2, -31, -5, 33, 25, 6, -3, 0, -8, 33, 119, 202},
  {-6, -6, 7, 16, 20, -13, -1, -12, -25, -18, -23, 3, 32, 28, 21, -4, -1, 7, 43, 108, 160},
  {-9, -1, 11, 16, 21, -23, -3, 1, -47, -34, -12, 13, 30, 28, 32, 11, -4, 24, 47, 98, 114},
  {0, -5, 3, 3, 1, 6, 5, -11, -2, 3, -10, -23, 28, 4, -3, 0, -3, 1, -3, 93, 338},
  {-3, 0, -1, 10, 5, -2, 3, -9, -17, -2, -17, -13, 33, 14, 7, 6, 3, -6, 6, 103, 272},
  {-4, 11, 0, 12, 14, -43, -2, -50, 19, 6, -42, 31, 100, 46, -54, 10, 10, -22, 38, 66, 220},
  {-1, -4, 3, 3, 0, 9, -1, -4, -6, -2, -5, -16, 11, 7, 8, -5, -3, 12, -4, 74, 360},
  {-1, -2, 0, 2, -1, 7, -1, 0, -6, -3, 1, -12, 6, 0, 10, -2, -2, 14, -4, 36, 428},
  {-2, -8, 7, 5, 6, 3, 5, -13, -7, 2, -24, -13, 24, 16, 3, -3, -3, -4, 25, 118, 238},
  {-3, -7, 8, 7, 9, 3, 1, -10, -14, -11, -18, -14, 18, 19, 20, -7, -3, 12, 30, 111, 210},
  {-3, -7, 5, 9, 8, 5, 8, -4, -28, -16, -18, -15, 17, 15, 25, -1, -1, 15, 32, 112, 196},
  {-5, -6, 8, 11, 14, -1, -2, -7, -24, -32, -10, -5, 11, 19, 32, -4, 6, 34, 26, 106, 170},
  {-1, -3, -3, 7, -4, 12, 14, -7, -17, -4, -5, -25, 15, -1, 22, 0, 0, 1, 9, 100, 292},
  {0, -3, -14, 18, -3, 23, 11, 3, -42, -10, -9, -26, 4, 8, 36, 18, -1, -5, 38, 112, 196},
  {-4, -1, -7, 19, -10, 26, 7, -7, -53, 9, -15, -19, 2, 11, 45, 61, -17, -15, 56, 99, 138},
  {0, -3, 0, 2, -3, 7, 6, -11, 1, 3, -1, -23, 18, 3, 2, -2, -3, 3, -12, 92, 354},
  {-2, -5, 3, 6, 12, -1, 5, -14, -7, -5, -22, -11, 18, 21, 13, -8, 2, -2, 20, 109, 248},
  {-1, -9, 4, 10, 9, -1, 7, -25, 0, 6, -26, -8, 16, 27, 0, -5, 0, -14, 25, 105, 272},
  {0, -2, 2, 1, -1, 4, 0, -3, 0, 1, 3, -15, 12, -2, 1, 0, -2, 0, -7, 48, 432},
  {-1, -12, 15, -1, 7, 2, 1, -20, 6, 7, -23, -14, 27, 16, -9, -1, 3, -10, 3, 120, 280},
  {-5, -6, 4, 14, 11, -3, 11, -32, -5, 1, -24, -21, 42, 22, -3, 1, 0, -7, 22, 97, 274},
  {-1, -6, 4, 5, 2, 2, 9, -14, -5, 3, -2, -36, 35, -4, 10, 1, 2, -14, 17, 77, 342},
  {-1, -11, 8, 5, 8, 10, -9, -13, 0, 3, -10, -38, 58, 9, -30, 14, 6, -32, 49, 25, 410},
  {0, -1, 1, 0, 0, 2, -2, 0, -1, 0, 3, -7, 6, -5, 4, 0, 0, 0, -2, 16, 484},
  {0, -3, 3, 0, -1, 5, -4, -1, 0, 0, 3, -9, 1, 2, 4, -1, -3, 6, -5, 35, 448},
  {0, -6, 0, 8, -5, 15, 4, -12, -7, 4, -6, -29, 10, 14, 14, -4, -3, 1, 7, 111, 280},
  {-1, 1, -3, 5, 0, -5, 9, 6, -18, -1, -1, -14, 13, -12, 14, 11, 7, -18, 2, 114, 294},
  {-1, -1, -5, 13, -5, 4, 8, 1, -28, 10, -13, -22, 12, 3, 13, 30, 3, -22, 26, 114, 232},
  {0, -5, 2, 4, -3, 9, 2, -9, -2, 3, 5, -33, 14, 3, 11, -1, -3, 3, 4, 80, 344},
  {-2, -12, 7, 13, 8, 3, 7, -22, -12, 2, -19, -21, 22, 18, 15, -4, -1, -6, 28, 110, 244},
  {-1, -6, 8, 0, 4, -2, 8, -20, 8, 7, -16, -9, 17, 14, -16, 4, 2, -11, 0, 85, 360}
};
Int TComAdaptiveLoopFilter::m_pattern9x9Sym[41] = 
{
                   0,
               1,  2,  3,
           4,  5,  6,  7,  8,
       9, 10, 11, 12, 13, 14, 15,
  16, 17, 18, 19, 20, 19, 18, 17, 16,
      15, 14, 13, 12, 11, 10,  9, 
           8,  7,  6,  5,  4,
               3,  2,  1,
                   0
};
Int TComAdaptiveLoopFilter::m_weights9x9Sym[22] = 
{
                   2,
               2,  2,  2,   
           2,  2,  2,  2,  2, 
       2,  2,  2,  2,  2,  2,  2,  
   2,  2,  2,  2,  1,  1
};

Int TComAdaptiveLoopFilter::m_pattern9x9Sym_Quart[42] = 
{

   0,  0,  0,  0,  1,  0,  0,  0,  0,
   0,  0,  0,  2,  3,  4,  0,  0,  0,
   0,  0,  5,  6,  7,  8,  9,  0,  0,  
   0, 10, 11, 12, 13, 14, 15, 16,  0,
  17, 18, 19, 20, 21, 22
};
#else
Int TComAdaptiveLoopFilter::m_pattern9x9Sym[39] = 
{
                   0,
               1,  2,  3,
           4,  5,  6,  7,  8,
       9, 10, 11, 12, 13, 14, 15,
      16, 17, 18, 19, 18, 17, 16,
      15, 14, 13, 12, 11, 10,  9, 
           8,  7,  6,  5,  4,
               3,  2,  1,
                   0
};
Int TComAdaptiveLoopFilter::m_weights9x9Sym[21] = 
{
               2,  2,  2,   
           2,  2,  2,  2,  2, 
       2,  2,  2,  2,  2,  2,  2,  
   2,  2,  2,  2,  1,  1
};

Int TComAdaptiveLoopFilter::m_pattern9x9Sym_Quart[42] = 
{
   0,  0,  0,  0,  0,  0,  0,  0,  0,
   0,  0,  0,  1,  2,  3,  0,  0,  0,
   0,  0,  4,  5,  6,  7,  8,  0,  0,  
   0,  9, 10, 11, 12, 13, 14, 15,  0,
  16, 17, 18, 19, 20, 21
};
#endif

Int TComAdaptiveLoopFilter::m_pattern7x7Sym[25] = 
{
                   0,
             1,  2,  3,
       4,  5,  6,  7,  8,
       9, 10, 11, 12, 11, 10, 9,
           8,  7,  6,  5,  4,
           3,  2,  1,
             0
};

Int TComAdaptiveLoopFilter::m_weights7x7Sym[14] = 
{
                  2,  
              2,  2,  2,   
        2,  2,  2,  2,  2,    
      2,  2,  2,  1,  1
};

Int TComAdaptiveLoopFilter::m_pattern7x7Sym_Quart[42] = 
{
   0,  0,  0,  0,  0,  0,  0,  0,  0,
   0,  0,  0,  0,  1,  0,  0,  0,  0,
   0,  0,  0,  2,  3,  4,  0,  0,  0,
   0,  0,  5,  6,  7,  8,  9,  0,  0,  
   0, 10, 11, 12, 13, 14,  
};

Int TComAdaptiveLoopFilter::m_pattern5x5Sym[13] = 
{
                   0,
             1,  2,  3,
       4,  5,  6,  5,  4,
               3,  2,  1,
             0
};

Int TComAdaptiveLoopFilter::m_weights5x5Sym[8] = 
{
           2, 
        2, 2, 2,
     2, 2, 1, 1
};

Int TComAdaptiveLoopFilter::m_pattern5x5Sym_Quart[45] = 
{
   0,  0,  0,  0,  0,  0,  0,  0,  0,
   0,  0,  0,  0,  0,  0,  0,  0,  0,
   0,  0,  0,  0,  1,  0,  0,  0,  0,
   0,  0,  0,  2,  3,  4,  0,  0,  0,
   0,  0,  5,  6,  7,  8,  0,  0,  0,  
};

Int TComAdaptiveLoopFilter::m_pattern9x9Sym_9[39] = 
{
              12, 13, 14,  
          20, 21, 22, 23, 24, 
      28, 29, 30, 31, 32, 33, 34,      
  36, 37, 38, 39, 40, 39, 38, 37, 36, 
      34, 33, 32, 31, 30, 29, 28,  
          24, 23, 22, 21, 20, 
              14, 13, 12,
};

Int TComAdaptiveLoopFilter::m_pattern9x9Sym_7[25] = 
{    
               13,   
           21, 22, 23,  
       29, 30, 31, 32, 33,       
   37, 38, 39, 40, 39, 38, 37,  
       33, 32, 31, 30, 29,   
           23, 22, 21,  
               13  
                     
};

Int TComAdaptiveLoopFilter::m_pattern9x9Sym_5[13] = 
{
          22, 
      30, 31, 32,    
  38, 39, 40, 39, 38, 
      32, 31, 30, 
          22,  
 };

Int* TComAdaptiveLoopFilter::m_patternTab_filt[m_NO_TEST_FILT] =
{
  m_pattern9x9Sym_9, m_pattern9x9Sym_7, m_pattern9x9Sym_5
}; 

Int* TComAdaptiveLoopFilter::m_patternTab[m_NO_TEST_FILT] =
{
  m_pattern9x9Sym, m_pattern7x7Sym, m_pattern5x5Sym
}; 

Int* TComAdaptiveLoopFilter::m_patternMapTab[m_NO_TEST_FILT] =
{
  m_pattern9x9Sym_Quart, m_pattern7x7Sym_Quart, m_pattern5x5Sym_Quart
};

Int* TComAdaptiveLoopFilter::m_weightsTab[m_NO_TEST_FILT] =
{
  m_weights9x9Sym, m_weights7x7Sym, m_weights5x5Sym
};

Int TComAdaptiveLoopFilter::m_flTab[m_NO_TEST_FILT] =
{
  9/2, 7/2, 5/2
};

Int TComAdaptiveLoopFilter::m_sqrFiltLengthTab[m_NO_TEST_FILT] =
{
  m_SQR_FILT_LENGTH_9SYM, m_SQR_FILT_LENGTH_7SYM, m_SQR_FILT_LENGTH_5SYM
};


#if JVET_C0038_GALF
const Int TComAdaptiveLoopFilter:: depthInt9x9Cut[21] = 
{
              1, 
           1, 2, 1,
        1, 2, 3, 2, 1,
     1, 2, 3, 4, 3, 2, 1,
  1, 2, 3, 4, 5,
};

const Int TComAdaptiveLoopFilter:: depthInt7x7Cut[14] = 
{
           1, 
        1, 2, 1,
     1, 2, 3, 2, 1, 
  1, 2, 3, 4, 4 
};


const Int TComAdaptiveLoopFilter:: depthInt5x5Cut[8] = 
{
        1,  
     1, 2, 1,
  1, 2, 3, 3  
};
#else
const Int TComAdaptiveLoopFilter::m_depthInt9x9Sym[21] = 
{
           5, 6, 5, 
        5, 6, 7, 6, 5,
     5, 6, 7, 8, 7, 6, 5,
  5, 6, 7, 8, 9, 9 
};

const Int TComAdaptiveLoopFilter::m_depthInt7x7Sym[14] = 
{
           4, 
        4, 5, 4, 
     4, 5, 6, 5, 4, 
  4, 5, 6, 7, 7 
};

const Int TComAdaptiveLoopFilter::m_depthInt5x5Sym[8] = 
{
        3,   
     3, 4, 3,
  3, 4, 5, 5  
};
#endif

const Int* TComAdaptiveLoopFilter::m_pDepthIntTab[m_NO_TEST_FILT] =
{
#if JVET_C0038_GALF
  depthInt5x5Cut,   depthInt7x7Cut,   depthInt9x9Cut, 
#else
  m_depthInt5x5Sym, m_depthInt7x7Sym, m_depthInt9x9Sym
#endif
};


// scaling factor for quantization of filter coefficients (9x9)
const Int TComAdaptiveLoopFilter::m_aiSymmetricMag9x9[41] =
{
  2, 2, 2, 2, 2, 2, 2, 2, 2,
  2, 2, 2, 2, 2, 2, 2, 2, 2,
  2, 2, 2, 2, 2, 2, 2, 2, 2,
  2, 2, 2, 2, 2, 2, 2, 2, 2,
  2, 2, 2, 2, 1
};

// scaling factor for quantization of filter coefficients (7x7)
const Int TComAdaptiveLoopFilter::m_aiSymmetricMag7x7[25] =
{
  2, 2, 2, 2, 2, 2, 2,
  2, 2, 2, 2, 2, 2, 2,
  2, 2, 2, 2, 2, 2, 2,
  2, 2, 2, 1
};

#if !JVET_C0038_GALF 
// scaling factor for quantization of filter coefficients (5x5)
const Int TComAdaptiveLoopFilter::m_aiSymmetricMag5x5[13] =
{
  2, 2, 2, 2, 2,
  2, 2, 2, 2, 2,
  2, 2, 1
};
#endif


const Int TComAdaptiveLoopFilter::m_aiSymmetricMag9x7[32] =
{
  2, 2, 2, 2, 2, 2, 2, 2, 2,
  2, 2, 2, 2, 2, 2, 2, 2, 2,
  2, 2, 2, 2, 2, 2, 2, 2, 2,
  2, 2, 2, 2, 1
};


// ====================================================================================================================
// Constructor / destructor / create / destroy
// ====================================================================================================================

TComAdaptiveLoopFilter::TComAdaptiveLoopFilter()
{
  m_img_height = 0;
  m_img_width = 0;
  m_nInputBitDepth = 0;
  m_pcTempPicYuv = NULL;
  m_imgY_var = NULL;
  m_imgY_temp = NULL;
  m_imgY_ver = NULL;
  m_imgY_hor = NULL;
#if JVET_C0038_GALF
  m_imgY_dig0 = NULL;
  m_imgY_dig1 = NULL;
#endif
  m_filterCoeffSym = NULL;
#if JVET_C0038_GALF
  m_filterCoeffFinal = NULL;
#endif
  m_filterCoeffPrevSelected = NULL;
  m_filterCoeffTmp = NULL;
  m_filterCoeffSymTmp = NULL;
  m_varImgMethods = NULL;
  m_filterCoeffShort = NULL;
  m_alfClipTable = NULL;
  m_alfClipOffset = 0;
}

Void TComAdaptiveLoopFilter:: xError(const char *text, int code)
{
  fprintf(stderr, "%s\n", text);
  exit(code);
}

Void TComAdaptiveLoopFilter:: no_mem_exit(const char *where)
{
  char errortext[200];
  sprintf(errortext, "Could not allocate memory: %s",where);
  xError (errortext, 100);
}

Void TComAdaptiveLoopFilter::initMatrix_imgpel(imgpel ***m2D, int d1, int d2)
{
  int i;
  
  if(!(*m2D = (imgpel **) calloc(d1, sizeof(imgpel *))))
    FATAL_ERROR_0("initMatrix_imgpel: memory allocation problem\n", -1);
  if(!((*m2D)[0] = (imgpel *) calloc(d1 * d2, sizeof(imgpel))))
    FATAL_ERROR_0("initMatrix_imgpel: memory allocation problem\n", -1);
  
  for(i = 1; i < d1; i++)
    (*m2D)[i] = (*m2D)[i-1] + d2;
}

Void TComAdaptiveLoopFilter::initMatrix_int(int ***m2D, int d1, int d2)
{
  int i;
  
  if(!(*m2D = (int **) calloc(d1, sizeof(int *))))
    FATAL_ERROR_0("initMatrix_int: memory allocation problem\n", -1);
  if(!((*m2D)[0] = (int *) calloc(d1 * d2, sizeof(int))))
    FATAL_ERROR_0("initMatrix_int: memory allocation problem\n", -1);
  
  for(i = 1; i < d1; i++)
    (*m2D)[i] = (*m2D)[i-1] + d2;
}

Void TComAdaptiveLoopFilter::initMatrix_short(short ***m2D, int d1, int d2)
{
  int i;
  
  if(!(*m2D = (short **) calloc(d1, sizeof(short *))))
    FATAL_ERROR_0("initMatrix_int: memory allocation problem\n", -1);
  if(!((*m2D)[0] = (short *) calloc(d1 * d2, sizeof(short))))
    FATAL_ERROR_0("initMatrix_int: memory allocation problem\n", -1);
  
  for(i = 1; i < d1; i++)
    (*m2D)[i] = (*m2D)[i-1] + d2;
}

Void TComAdaptiveLoopFilter::destroyMatrix_short(short **m2D)
{
  if(m2D)
  {
    if(m2D[0])
      free(m2D[0]);
    else
      FATAL_ERROR_0("destroyMatrix_int: memory free problem\n", -1);
    free(m2D);
  } 
}

Void TComAdaptiveLoopFilter::destroyMatrix_int(int **m2D)
{
  if(m2D)
  {
    if(m2D[0])
      free(m2D[0]);
    else
      FATAL_ERROR_0("destroyMatrix_int: memory free problem\n", -1);
    free(m2D);
  } 
}

Void TComAdaptiveLoopFilter::destroyMatrix_imgpel(imgpel **m2D)
{
  if(m2D)
  {
    if(m2D[0])
      free(m2D[0]);
    else
      FATAL_ERROR_0("destroyMatrix_imgpel: memory free problem\n", -1);
    free(m2D);
  } 
}

Void TComAdaptiveLoopFilter::get_mem2Dpel(imgpel ***array2D, int rows, int columns)
{
  int i;
  
  if((*array2D      = (imgpel**)calloc(rows,        sizeof(imgpel*))) == NULL)
    no_mem_exit("get_mem2Dpel: array2D");
  if(((*array2D)[0] = (imgpel* )calloc(rows*columns,sizeof(imgpel ))) == NULL)
    no_mem_exit("get_mem2Dpel: array2D");
  
  for(i=1 ; i<rows ; i++)
    (*array2D)[i] =  (*array2D)[i-1] + columns  ;
}

Void TComAdaptiveLoopFilter::free_mem2Dpel(imgpel **array2D)
{
  if (array2D)
  {
    if (array2D[0])
      free (array2D[0]);
    else xError ("free_mem2Dpel: trying to free unused memory",100);
    
    free (array2D);
  }
}

Void TComAdaptiveLoopFilter::initMatrix_double(double ***m2D, int d1, int d2)
{
  int i;
  
  if(!(*m2D = (double **) calloc(d1, sizeof(double *))))
    FATAL_ERROR_0("initMatrix_double: memory allocation problem\n", -1);
  if(!((*m2D)[0] = (double *) calloc(d1 * d2, sizeof(double))))
    FATAL_ERROR_0("initMatrix_double: memory allocation problem\n", -1);
  
  for(i = 1; i < d1; i++)
    (*m2D)[i] = (*m2D)[i-1] + d2;
}

Void TComAdaptiveLoopFilter::initMatrix3D_double(double ****m3D, int d1, int d2, int d3)
{
  int  j;
  
  if(!((*m3D) = (double ***) calloc(d1, sizeof(double **))))
    FATAL_ERROR_0("initMatrix3D_double: memory allocation problem\n", -1);
  
  for(j = 0; j < d1; j++)
    initMatrix_double((*m3D) + j, d2, d3);
}


Void TComAdaptiveLoopFilter::initMatrix4D_double(double *****m4D, int d1, int d2, int d3, int d4)
{
  int  j;
  
  if(!((*m4D) = (double ****) calloc(d1, sizeof(double ***))))
    FATAL_ERROR_0("initMatrix4D_double: memory allocation problem\n", -1);
  
  for(j = 0; j < d1; j++)
    initMatrix3D_double((*m4D) + j, d2, d3, d4);
}


Void TComAdaptiveLoopFilter::destroyMatrix_double(double **m2D)
{
  if(m2D)
  {
    if(m2D[0])
      free(m2D[0]);
    else
      FATAL_ERROR_0("destroyMatrix_double: memory free problem\n", -1);
    free(m2D);
  } 
  else
  {
    FATAL_ERROR_0("destroyMatrix_double: memory free problem\n", -1);
  }
}

Void TComAdaptiveLoopFilter::destroyMatrix3D_double(double ***m3D, int d1)
{
  int i;
  
  if(m3D)
  {
    for(i = 0; i < d1; i++)
      destroyMatrix_double(m3D[i]);
    free(m3D);
  } 
  else
  {
    FATAL_ERROR_0("destroyMatrix3D_double: memory free problem\n", -1);
  }
}


Void TComAdaptiveLoopFilter::destroyMatrix4D_double(double ****m4D, int d1, int d2)
{
  int  j;
  
  if(m4D)
  {
    for(j = 0; j < d1; j++)
      destroyMatrix3D_double(m4D[j], d2);
    free(m4D);
  } 
  else
  {
    FATAL_ERROR_0("destroyMatrix4D_double: memory free problem\n", -1);
  }
}

Void TComAdaptiveLoopFilter::create( Int iPicWidth, Int iPicHeight, ChromaFormat chromaFormatIDC, Int uiMaxCUWidth, UInt uiMaxCUHeight, UInt uiMaxCUDepth , Int nInputBitDepth , Int nInternalBitDepth )
{
  if( iPicWidth == m_img_width && iPicHeight == m_img_height && nInputBitDepth == m_nInputBitDepth && nInternalBitDepth == m_nInternalBitDepth )
  {
    m_pcTempPicYuv->setBorderExtension( false );
    return;
  }
  destroy();
  m_nInputBitDepth = nInputBitDepth;
  m_nInternalBitDepth = nInternalBitDepth;
  m_nBitIncrement = nInternalBitDepth - 8; // according to ALF on HM-3
  m_nIBDIMax = ( 1 << m_nInternalBitDepth ) - 1;
  m_uiMaxTotalCUDepth = uiMaxCUDepth;

  assert( m_nBitIncrement >= 0 );
  if ( !m_pcTempPicYuv )
  {
    m_pcTempPicYuv = new TComPicYuv;
    m_pcTempPicYuv->create( iPicWidth, iPicHeight, chromaFormatIDC, uiMaxCUWidth, uiMaxCUHeight, uiMaxCUDepth , true);
  }
  m_img_height = iPicHeight;
  m_img_width = iPicWidth;
#if JVET_C0038_GALF
  Int iPadOffset = max(2, JVET_C0038_SHIFT_VAL_HALFW);
  initMatrix_int(&m_imgY_temp, m_ALF_WIN_VERSIZE+2*iPadOffset+3, m_ALF_WIN_HORSIZE+2*iPadOffset+3);
  initMatrix_int(&m_imgY_ver,  m_ALF_WIN_VERSIZE+2*iPadOffset+3, m_ALF_WIN_HORSIZE+2*iPadOffset+3);
  initMatrix_int(&m_imgY_hor,  m_ALF_WIN_VERSIZE+2*iPadOffset+3, m_ALF_WIN_HORSIZE+2*iPadOffset+3);
  initMatrix_int(&m_imgY_dig0,  m_ALF_WIN_VERSIZE+2*iPadOffset+3, m_ALF_WIN_HORSIZE+2*iPadOffset+3);
  initMatrix_int(&m_imgY_dig1,  m_ALF_WIN_VERSIZE+2*iPadOffset+3, m_ALF_WIN_HORSIZE+2*iPadOffset+3);
#else
  initMatrix_int(&m_imgY_temp, m_ALF_WIN_VERSIZE+2*m_VAR_SIZE+3, m_ALF_WIN_HORSIZE+2*m_VAR_SIZE+3);
  initMatrix_int(&m_imgY_ver, m_ALF_WIN_VERSIZE+2*m_VAR_SIZE+3, m_ALF_WIN_HORSIZE+2*m_VAR_SIZE+3);
  initMatrix_int(&m_imgY_hor, m_ALF_WIN_VERSIZE+2*m_VAR_SIZE+3, m_ALF_WIN_HORSIZE+2*m_VAR_SIZE+3);
#endif

  get_mem2Dpel(&m_varImgMethods, m_img_height, m_img_width);
  initMatrix_int(&m_filterCoeffSym, m_NO_VAR_BINS, m_MAX_SQR_FILT_LENGTH);
  initMatrix_int(&m_filterCoeffPrevSelected, m_NO_VAR_BINS, m_MAX_SQR_FILT_LENGTH); 
  initMatrix_int(&m_filterCoeffTmp, m_NO_VAR_BINS, m_MAX_SQR_FILT_LENGTH);      
  initMatrix_int(&m_filterCoeffSymTmp, m_NO_VAR_BINS, m_MAX_SQR_FILT_LENGTH);   

  initMatrix_short(&m_filterCoeffShort, m_NO_VAR_BINS, m_MAX_SQR_FILT_LENGTH);
#if JVET_C0038_GALF
  initMatrix_int(&m_filterCoeffFinal, m_NO_VAR_BINS, (m_MAX_SQR_FILT_LENGTH/2+1));
#endif
}

Void TComAdaptiveLoopFilter::destroy()
{
  if ( m_pcTempPicYuv )
  {
    m_pcTempPicYuv->destroy();
    delete m_pcTempPicYuv;
    m_pcTempPicYuv = NULL;
  }
  destroyMatrix_int(m_imgY_temp);

  destroyMatrix_int(m_imgY_ver);
  destroyMatrix_int(m_imgY_hor);
#if JVET_C0038_GALF
  destroyMatrix_int(m_imgY_dig0);
  destroyMatrix_int(m_imgY_dig1);
#endif
  free_mem2Dpel(m_varImgMethods);
  destroyMatrix_short(m_filterCoeffShort);

  if( m_alfClipTable )
  {
    free( m_alfClipTable );
    m_alfClipTable = NULL;
  }

  destroyMatrix_int(m_filterCoeffSym);
  destroyMatrix_int(m_filterCoeffPrevSelected);
  destroyMatrix_int(m_filterCoeffTmp);
  destroyMatrix_int(m_filterCoeffSymTmp);
#if JVET_C0038_GALF
  destroyMatrix_int(m_filterCoeffFinal);
#endif
}

// ====================================================================================================================
// Public member functions
// ====================================================================================================================

Int TComAdaptiveLoopFilter::ALFTapHToTapV(Int tapH)
{
#if JVET_C0038_GALF
  return tapH;
#else
  return min<UInt>(tapH, 7);
#endif
}

Int TComAdaptiveLoopFilter::ALFFlHToFlV(Int flH)
{
#if JVET_C0038_GALF
  return flH;
#else
  return min<UInt>(flH, 7/2);
#endif
}

Int TComAdaptiveLoopFilter::ALFTapHToNumCoeff(Int tapH)
{
  Int num_coeff;
  
  num_coeff = (Int)(tapH*tapH)/4 + 2;
#if JVET_C0038_GALF
  num_coeff -= 1;
#else
  if (tapH == 9)
    num_coeff -= 1;
  else
    assert(tapH < 9);
#endif
  return num_coeff;
}

// --------------------------------------------------------------------------------------------------------------------
// allocate / free / copy functions
// --------------------------------------------------------------------------------------------------------------------

Void TComAdaptiveLoopFilter::allocALFParam(ALFParam* pAlfParam)
{
  pAlfParam->alf_flag = 0;
  pAlfParam->cu_control_flag = 0;
  pAlfParam->alf_max_depth = 0;
#if JVET_C0038_GALF 
  pAlfParam->iAvailableFilters = JVET_C0038_NO_PREV_FILTERS;
  pAlfParam->iPredPattern = 0;
#else
  pAlfParam->coeff        = new Int[m_ALF_MAX_NUM_COEF];
  ::memset(pAlfParam->coeff,        0, sizeof(Int)*m_ALF_MAX_NUM_COEF   );
#endif
  pAlfParam->coeff_chroma = new Int[m_ALF_MAX_NUM_COEF_C];
  ::memset(pAlfParam->coeff_chroma, 0, sizeof(Int)*m_ALF_MAX_NUM_COEF_C );

  pAlfParam->coeffmulti = new Int*[m_NO_VAR_BINS];

  for (int i=0; i<m_NO_VAR_BINS; i++)
  {
    pAlfParam->coeffmulti[i] = new Int[m_ALF_MAX_NUM_COEF];
    ::memset(pAlfParam->coeffmulti[i],        0, sizeof(Int)*m_ALF_MAX_NUM_COEF );
  }
  pAlfParam->num_cus_in_frame = m_uiNumCUsInFrame;
  pAlfParam->num_alf_cu_flag  = 0;
  pAlfParam->alf_cu_flag      = new UInt[(m_uiNumCUsInFrame << ((m_uiMaxTotalCUDepth-1)*2))];
  ::memset(pAlfParam->kMinTab , 0 , sizeof( pAlfParam->kMinTab ) );

#if COM16_C806_ALF_TEMPPRED_NUM
  pAlfParam->temproalPredFlag = false;
  pAlfParam->prevIdx = -1;
  pAlfParam->alfCoeffLuma   = new Int*[m_NO_VAR_BINS];
  for (int i=0; i<m_NO_VAR_BINS; i++)
  {
    pAlfParam->alfCoeffLuma[i] = new Int[m_ALF_MAX_NUM_COEF];
    ::memset(pAlfParam->alfCoeffLuma[i],        0, sizeof(Int)*m_ALF_MAX_NUM_COEF );
  }

  pAlfParam->alfCoeffChroma = new Int[m_ALF_MAX_NUM_COEF_C];
  ::memset(pAlfParam->alfCoeffChroma,        0, sizeof(Int)*m_ALF_MAX_NUM_COEF_C );
#endif
}
#if !JVET_C0038_GALF
Void TComAdaptiveLoopFilter::printALFParam(ALFParam* pAlfParam , Bool bDecoder)
{
  Int FiltLengthTab[] = {22, 14, 8}; //0:9tap
  Int FiltLength = FiltLengthTab[pAlfParam->realfiltNo];

  printf( "\nALF param" );

  printf( "\nalf_flag %d" , pAlfParam->alf_flag );
  if( pAlfParam->alf_flag == 0 )
  {
    printf( "\n" );
    return;
  }
  printf( "\nrealfiltNo %d" , pAlfParam->realfiltNo );
  printf( "\nnoFilters %d" , pAlfParam->noFilters - bDecoder );
  printf( "\nfilterPattern" );
  for( Int n = 0 ; n < 16 ; n++ )
    printf( "(%d)%d, " , n , pAlfParam->filterPattern[n] );
  printf( "\npredMethod %d" , pAlfParam->predMethod );
  printf( "\nminKStart %d" , pAlfParam->minKStart );
  printf( "\nkMinTab " );
  for( Int n = 0 ; n < 42 ; n++ )
    printf( "(%d)%d, " , n , pAlfParam->kMinTab[n] );
  for(Int ind=0; ind<pAlfParam->filters_per_group_diff; ind++)
  {
    printf("\ncoeffmulti(%d):", ind);
    for (Int i=0; i<FiltLength; i++) printf("%d ", pAlfParam->coeffmulti[ind][i]);
  }
  printf( "\nchroma_idc %d" , pAlfParam->chroma_idc );
  printf( "\ntap_chroma %d" , pAlfParam->tap_chroma );
  printf( "\ncu_control_flag %d" , pAlfParam->cu_control_flag );
  printf( "\nalf_max_depth %d" , pAlfParam->alf_max_depth );
  printf( "\nnum_alf_cu_flag %d" , pAlfParam->num_alf_cu_flag );

  printf( "\nvarIndTab: " );
  for( Int i = 0 ; i < ALF_NO_VAR_BIN ; i++ )
    printf( "(%d)%d " , i , pAlfParam->varIndTab[i]  );

  printf("\n");
}
#endif

Void TComAdaptiveLoopFilter::freeALFParam(ALFParam* pAlfParam)
{
  assert(pAlfParam != NULL);
#if !JVET_C0038_GALF  
  if (pAlfParam->coeff != NULL)
  {
    delete[] pAlfParam->coeff;
    pAlfParam->coeff = NULL;
  }
#endif
  if (pAlfParam->coeff_chroma != NULL)
  {
    delete[] pAlfParam->coeff_chroma;
    pAlfParam->coeff_chroma = NULL;
  }


  if( pAlfParam->coeffmulti != NULL )
  {
    for (int i=0; i<m_NO_VAR_BINS; i++)
    {
      delete[] pAlfParam->coeffmulti[i];
      pAlfParam->coeffmulti[i] = NULL;
    }
    delete[] pAlfParam->coeffmulti;
    pAlfParam->coeffmulti = NULL;
  }

  if(pAlfParam->alf_cu_flag != NULL)
  {
    delete[] pAlfParam->alf_cu_flag;
    pAlfParam->alf_cu_flag = NULL;
  }
#if COM16_C806_ALF_TEMPPRED_NUM
  if( pAlfParam->alfCoeffLuma != NULL )
  {
    for (int i=0; i<m_NO_VAR_BINS; i++)
    {
      delete[] pAlfParam->alfCoeffLuma[i];
      pAlfParam->alfCoeffLuma[i] = NULL;
    }
    delete[] pAlfParam->alfCoeffLuma;
    pAlfParam->alfCoeffLuma = NULL;
  }

  if( pAlfParam->alfCoeffChroma != NULL )
  {
    delete[] pAlfParam->alfCoeffChroma;
    pAlfParam->alfCoeffChroma = NULL;
  }
#endif
}

Void TComAdaptiveLoopFilter::copyALFParam(ALFParam* pDesAlfParam, ALFParam* pSrcAlfParam)
{
#if COM16_C806_ALF_TEMPPRED_NUM
  if( !pDesAlfParam->temproalPredFlag )
  {
#endif
  pDesAlfParam->alf_flag = pSrcAlfParam->alf_flag;
  pDesAlfParam->cu_control_flag = pSrcAlfParam->cu_control_flag;
  pDesAlfParam->chroma_idc = pSrcAlfParam->chroma_idc;
#if COM16_C806_ALF_TEMPPRED_NUM
  }
#endif
  pDesAlfParam->tap = pSrcAlfParam->tap;
  pDesAlfParam->tapV = pSrcAlfParam->tapV;
  pDesAlfParam->num_coeff = pSrcAlfParam->num_coeff;

  pDesAlfParam->tap_chroma = pSrcAlfParam->tap_chroma;
  pDesAlfParam->num_coeff_chroma = pSrcAlfParam->num_coeff_chroma;
#if !JVET_C0038_GALF
  ::memcpy(pDesAlfParam->coeff, pSrcAlfParam->coeff, sizeof(Int)*m_ALF_MAX_NUM_COEF);
#endif
  ::memcpy(pDesAlfParam->coeff_chroma, pSrcAlfParam->coeff_chroma, sizeof(Int)*m_ALF_MAX_NUM_COEF_C);

  pDesAlfParam->realfiltNo = pSrcAlfParam->realfiltNo;
  pDesAlfParam->filtNo = pSrcAlfParam->filtNo;
  ::memcpy(pDesAlfParam->filterPattern, pSrcAlfParam->filterPattern, sizeof(Int)*m_NO_VAR_BINS);
#if JVET_C0038_GALF
  ::memcpy(pDesAlfParam->PrevFiltIdx,   pSrcAlfParam->PrevFiltIdx,   sizeof(Char) *m_NO_VAR_BINS);
  ::memcpy(pDesAlfParam->codedVarBins,  pSrcAlfParam->codedVarBins,  sizeof(Bool) *m_NO_VAR_BINS);
  pDesAlfParam->iAvailableFilters = pSrcAlfParam->iAvailableFilters;
  pDesAlfParam->forceCoeff0       = pSrcAlfParam->forceCoeff0;
  pDesAlfParam->iPredPattern      = pSrcAlfParam->iPredPattern;
#endif
  pDesAlfParam->startSecondFilter = pSrcAlfParam->startSecondFilter;
  pDesAlfParam->noFilters = pSrcAlfParam->noFilters;
  
  //Coeff send related
  pDesAlfParam->filters_per_group_diff = pSrcAlfParam->filters_per_group_diff; //this can be updated using codedVarBins
  pDesAlfParam->filters_per_group = pSrcAlfParam->filters_per_group; //this can be updated using codedVarBins
#if !JVET_C0038_GALF
  ::memcpy(pDesAlfParam->codedVarBins, pSrcAlfParam->codedVarBins, sizeof(Int)*m_NO_VAR_BINS);
  pDesAlfParam->forceCoeff0 = pSrcAlfParam->forceCoeff0;
#endif
  pDesAlfParam->predMethod = pSrcAlfParam->predMethod;
  for (int i=0; i<m_NO_VAR_BINS; i++)
  {
    ::memcpy(pDesAlfParam->coeffmulti[i], pSrcAlfParam->coeffmulti[i], sizeof(Int)*m_ALF_MAX_NUM_COEF);
#if COM16_C806_ALF_TEMPPRED_NUM
    ::memcpy(pDesAlfParam->alfCoeffLuma[i], pSrcAlfParam->alfCoeffLuma[i], sizeof(Int)*m_ALF_MAX_NUM_COEF);
#endif
  }
#if COM16_C806_ALF_TEMPPRED_NUM
  ::memcpy(pDesAlfParam->alfCoeffChroma, pSrcAlfParam->alfCoeffChroma, sizeof(Int)*m_ALF_MAX_NUM_COEF_C);
#endif
  pDesAlfParam->minKStart = pSrcAlfParam->minKStart;
  ::memcpy( pDesAlfParam->kMinTab , pSrcAlfParam->kMinTab , sizeof( pSrcAlfParam->kMinTab ) );

  ::memcpy( pDesAlfParam->varIndTab , pSrcAlfParam->varIndTab , sizeof( pSrcAlfParam->varIndTab ) );

#if COM16_C806_ALF_TEMPPRED_NUM
  if( !pDesAlfParam->temproalPredFlag )
  {
#endif
  pDesAlfParam->num_alf_cu_flag = pSrcAlfParam->num_alf_cu_flag;
  ::memcpy(pDesAlfParam->alf_cu_flag, pSrcAlfParam->alf_cu_flag, sizeof(UInt)*pSrcAlfParam->num_alf_cu_flag);
#if COM16_C806_ALF_TEMPPRED_NUM
  }
#endif
}

Void TComAdaptiveLoopFilter::resetALFParam(ALFParam* pDesAlfParam)
{
  pDesAlfParam->alf_flag = 0;
  pDesAlfParam->cu_control_flag = 0;
  pDesAlfParam->chroma_idc = 0;
  pDesAlfParam->tap = 0;
  pDesAlfParam->tapV = 0;
  pDesAlfParam->num_coeff = 0;
#if JVET_C0038_GALF 
  pDesAlfParam->tap_chroma = m_ALF_MAX_NUM_TAP_C;
#else
  pDesAlfParam->tap_chroma = 0;
  pDesAlfParam->num_coeff_chroma = 0;
#endif  
#if JVET_C0038_GALF 
  pDesAlfParam->iAvailableFilters = JVET_C0038_NO_PREV_FILTERS;
  pDesAlfParam->forceCoeff0       = false;
  pDesAlfParam->iPredPattern      = 0;
#endif

#if !JVET_C0038_GALF
  ::memset(pDesAlfParam->coeff, 0, sizeof(Int)*m_ALF_MAX_NUM_COEF);
#endif
  ::memset(pDesAlfParam->coeff_chroma, 0, sizeof(Int)*m_ALF_MAX_NUM_COEF_C);
  pDesAlfParam->realfiltNo = 0;
  pDesAlfParam->filtNo = 0;
  ::memset(pDesAlfParam->filterPattern, 0, sizeof(Int)*m_NO_VAR_BINS);
#if JVET_C0038_GALF
  ::memset(pDesAlfParam->PrevFiltIdx,   0, sizeof(Char)*m_NO_VAR_BINS);
  for(int ind = 0; ind < ALF_NO_VAR_BIN; ind++)
  {
    pDesAlfParam->codedVarBins[ind] = true;
  }
#endif
  pDesAlfParam->startSecondFilter = 0;
  pDesAlfParam->noFilters = 0;
  ::memset(pDesAlfParam->kMinTab , 0 , sizeof( pDesAlfParam->kMinTab ) );

  //Coeff send related
  pDesAlfParam->filters_per_group_diff = 0; //this can be updated using codedVarBins
  pDesAlfParam->filters_per_group = 0; //this can be updated using codedVarBins
#if !JVET_C0038_GALF
  ::memset(pDesAlfParam->codedVarBins, 0, sizeof(Int)*m_NO_VAR_BINS);
  pDesAlfParam->forceCoeff0 = 0;
#endif
  pDesAlfParam->predMethod = 0;
  for (int i=0; i<m_NO_VAR_BINS; i++)
  {
    ::memset(pDesAlfParam->coeffmulti[i], 0, sizeof(Int)*m_ALF_MAX_NUM_COEF);
#if COM16_C806_ALF_TEMPPRED_NUM
    ::memset(pDesAlfParam->alfCoeffLuma[i], 0, sizeof(Int)*m_ALF_MAX_NUM_COEF);
#endif
  }
#if COM16_C806_ALF_TEMPPRED_NUM
  ::memset(pDesAlfParam->alfCoeffChroma, 0, sizeof(Int)*m_ALF_MAX_NUM_COEF_C);
  pDesAlfParam->temproalPredFlag = false;
  pDesAlfParam->prevIdx = -1;
#endif

  ::memset( pDesAlfParam->varIndTab , 0 , sizeof( pDesAlfParam->varIndTab ) );

  pDesAlfParam->num_alf_cu_flag = 0;
}
#if JVET_C0038_GALF
Void TComAdaptiveLoopFilter::initVarForChroma  (ALFParam* pcAlfParam, Bool bUpdatedDCCoef)
{
  Int k, i;
  //initilization for clip operation in subfilterFrame()
  Int flipTableSize   = (m_ALF_HM3_QC_CLIP_RANGE <<m_nBitIncrement);
  m_alfClipOffset = (m_ALF_HM3_QC_CLIP_OFFSET<<m_nBitIncrement);

  if( m_alfClipTable )
  {
    free(m_alfClipTable);
  }

  m_alfClipTable = (imgpel *)calloc(flipTableSize, sizeof(imgpel));

  for( k=0; k< flipTableSize; k++)
  {
    m_alfClipTable[k] = max( 0, min( k-m_alfClipOffset, m_nIBDIMax ) );
  }
  Int filtNo = pcAlfParam->tap_chroma==9? 0: (pcAlfParam->tap_chroma==7?1: 2);
  if (!bUpdatedDCCoef)
  {
    Int * weights = TComAdaptiveLoopFilter::m_weightsTab[filtNo]; 
    Int quantCoeffSum=0;
    Int factor = (1 << (m_NUM_BITS-1)); 
    for (i=0; i< pcAlfParam->num_coeff_chroma - 1; i++)
    {
      quantCoeffSum += weights[i] * pcAlfParam->coeff_chroma [i];
    }
    pcAlfParam->coeff_chroma[pcAlfParam->num_coeff_chroma - 1] = factor - quantCoeffSum;
  }
  //fill in the ALF coefficients
  Int* patternMap = m_patternMapTab[filtNo];
  k=0;
  for( i = 0; i < m_MAX_SQR_FILT_LENGTH; i++)
  {
    if (patternMap[i]>0)
    {
      m_filterCoeffShort[0][i]=pcAlfParam->coeff_chroma[k];
      k++;
    }
    else
    {
      m_filterCoeffShort[0][i]=0;
    }
  }  
}
#endif
// --------------------------------------------------------------------------------------------------------------------
// prediction of filter coefficients
// --------------------------------------------------------------------------------------------------------------------
#if !JVET_C0038_GALF
Void TComAdaptiveLoopFilter::predictALFCoeff( ALFParam* pAlfParam)
{
  Int i, sum, pred, tap, N;
  const Int* pFiltMag = NULL;
  
  tap = pAlfParam->tap;
  Int tapV = pAlfParam->tapV;
  
  switch(tap)
  {
    case 5:
      pFiltMag = m_aiSymmetricMag5x5;
      break;
    case 7:
      pFiltMag = m_aiSymmetricMag7x7;
      break;
    case 9:
      pFiltMag = m_aiSymmetricMag9x7;
      break;
    default:
      assert(0);
      break;
  }
  N = (tap * tapV + 1) >> 1;
  sum=0;
  for(i=0; i<N-1;i++)
  {
    sum+=pFiltMag[i]*pAlfParam->coeff[i];
  }
  pred=(1<<m_ALF_NUM_BIT_SHIFT)-sum;
  pAlfParam->coeff[N-1]=pred-pAlfParam->coeff[N-1];
}

Void TComAdaptiveLoopFilter::predictALFCoeffChroma( ALFParam* pAlfParam )
{
  Int i, sum, pred, tap, N;
  const Int* pFiltMag = NULL;
  
  tap = pAlfParam->tap_chroma;
  switch(tap)
  {
    case 5:
      pFiltMag = m_aiSymmetricMag5x5;
      break;
    case 7:
      pFiltMag = m_aiSymmetricMag7x7;
      break;
    case 9:
      pFiltMag = m_aiSymmetricMag9x9;
      break;
    default:
      assert(0);
      break;
  }
  N = (tap*tap+1)>>1;
  sum=0;
  for(i=0; i<N;i++)
  {
    sum+=pFiltMag[i]*pAlfParam->coeff_chroma[i];
  }
  pred=(1<<m_ALF_NUM_BIT_SHIFT)-(sum-pAlfParam->coeff_chroma[N-1]);
  pAlfParam->coeff_chroma[N-1]=pred-pAlfParam->coeff_chroma[N-1];
}
#endif

// --------------------------------------------------------------------------------------------------------------------
// interface function for actual ALF process
// --------------------------------------------------------------------------------------------------------------------

/**
 \param pcPic         picture (TComPic) class (input/output)
 \param pcAlfParam    ALF parameter
 \todo   for temporal buffer, it uses residual picture buffer, which may not be safe. Make it be safer.
 */
Void TComAdaptiveLoopFilter::ALFProcess(TComPic* pcPic, ALFParam* pcAlfParam)
{
  if(!pcAlfParam->alf_flag)
  {
    return;
  }
#if JVET_C0024_QTBT
  pcPic->getSlice(0)->setTextType(CHANNEL_TYPE_LUMA);  //cu level on off only for luma
#endif  
  m_pcTempPicYuv = pcPic->replacePicYuvRecPointer( m_pcTempPicYuv );
  TComPicYuv* pcPicYuvRec    = pcPic->getPicYuvRec();
  TComPicYuv* pcPicYuvExtRec = m_pcTempPicYuv;
  pcPicYuvExtRec->setBorderExtension ( false );
#if JVET_C0038_GALF
  pcPicYuvExtRec->extendPicBorder    (m_PADDING_W_ALF);
  m_max_NO_VAR_BINS = TComAdaptiveLoopFilter::m_NO_VAR_BINS ;
  m_max_NO_FILTERS  = TComAdaptiveLoopFilter::m_NO_FILTERS  ;
#else
  pcPicYuvExtRec->extendPicBorder    (m_FILTER_LENGTH >> 1);
#endif

  if(pcAlfParam->cu_control_flag)
  {
    UInt idx = 0;
    for(UInt uiCUAddr = 0; uiCUAddr < pcPic->getNumberOfCtusInFrame(); uiCUAddr++)
    {
      TComDataCU *pcCU = pcPic->getCtu(uiCUAddr);
#if JVET_C0024_QTBT
      setAlfCtrlFlags(pcAlfParam, pcCU, 0, 0, pcCU->getSlice()->getSPS()->getCTUSize(), pcCU->getSlice()->getSPS()->getCTUSize(), idx);
#else
      setAlfCtrlFlags(pcAlfParam, pcCU, 0, 0, idx);
#endif
    }
  }
  xALFLuma_qc(pcPic, pcAlfParam, pcPicYuvExtRec, pcPicYuvRec);
  
  if(pcAlfParam->chroma_idc)
  {
#if JVET_C0038_GALF
#if COM16_C806_ALF_TEMPPRED_NUM
    initVarForChroma(pcAlfParam, (pcAlfParam->temproalPredFlag ? true : false));
#else
    initVarForChroma(pcAlfParam, false);
#endif
#else
#if COM16_C806_ALF_TEMPPRED_NUM
    if( !pcAlfParam->temproalPredFlag )
#endif
    predictALFCoeffChroma(pcAlfParam);
#endif

#if COM16_C806_ALF_TEMPPRED_NUM
    memcpy( pcAlfParam->alfCoeffChroma, pcAlfParam->coeff_chroma, sizeof(Int)*m_ALF_MAX_NUM_COEF_C );
#endif
    xALFChroma( pcAlfParam, pcPicYuvExtRec, pcPicYuvRec);
  }
  else
  {
    pcPicYuvExtRec->copyToPic( pcPicYuvRec , COMPONENT_Cb , false );
    pcPicYuvExtRec->copyToPic( pcPicYuvRec , COMPONENT_Cr , false );
  }
}

// ====================================================================================================================
// Protected member functions
// ====================================================================================================================

// --------------------------------------------------------------------------------------------------------------------
// ALF for luma
// --------------------------------------------------------------------------------------------------------------------
Void TComAdaptiveLoopFilter::xALFLuma_qc(TComPic* pcPic, ALFParam* pcAlfParam, TComPicYuv* pcPicDec, TComPicYuv* pcPicRest)
{
  Int    LumaStride = pcPicDec->getStride(COMPONENT_Y);
  imgpel* pDec = (imgpel*)pcPicDec->getAddr(COMPONENT_Y);
  imgpel* pRest = (imgpel*)pcPicRest->getAddr(COMPONENT_Y);
  
  //Decode and reconst filter coefficients
  DecFilter_qc(pDec,pcAlfParam,LumaStride);
  //set maskImg using cu adaptive one.

  m_imgY_var       = m_varImgMethods;

  if(pcAlfParam->cu_control_flag)
  {
    xCUAdaptive_qc(pcPic, pcAlfParam, pRest, pDec, LumaStride);
  }  
  else
  {
    //then do whole frame filtering
#if JVET_C0038_GALF
    filterFrame(pRest, pDec, pcAlfParam, LumaStride);
#else
    filterFrame(pRest, pDec, pcAlfParam->realfiltNo, LumaStride);
#endif
  }
}

Void TComAdaptiveLoopFilter::DecFilter_qc(imgpel* imgY_rec,ALFParam* pcAlfParam, int Stride)
{
  int i;
  int numBits = m_NUM_BITS; 
  int **pfilterCoeffSym;
  pfilterCoeffSym= m_filterCoeffSym;
#if COM16_C806_ALF_TEMPPRED_NUM
  if( pcAlfParam->temproalPredFlag )
  {
#if JVET_C0038_GALF
    for(i = 0; i < m_max_NO_VAR_BINS; i++)
#else
    for(i = 0; i < m_NO_VAR_BINS; i++)
#endif
    {
      memcpy(pfilterCoeffSym[i], &pcAlfParam->alfCoeffLuma[i][0] ,sizeof(int)*m_MAX_SQR_FILT_LENGTH);
    }

    int k, varInd;
    int *patternMap;
    int *patternMapTab[3]={m_pattern9x9Sym_Quart, m_pattern7x7Sym_Quart, m_pattern5x5Sym_Quart};
    {
#if JVET_C0038_GALF
      for(varInd=0; varInd<m_max_NO_VAR_BINS; ++varInd)
#else
      for(varInd=0; varInd<m_NO_VAR_BINS; ++varInd)
#endif
      {
        memset(m_filterCoeffPrevSelected[varInd],0,sizeof(int)*m_MAX_SQR_FILT_LENGTH);
      }
      patternMap=patternMapTab[pcAlfParam->realfiltNo];
#if JVET_C0038_GALF
      for(varInd=0; varInd<m_max_NO_VAR_BINS; ++varInd)
#else
      for(varInd=0; varInd<m_NO_VAR_BINS; ++varInd)
#endif
      {
        k=0;
        for(i = 0; i < m_MAX_SQR_FILT_LENGTH; i++)
        {
          if (patternMap[i]>0)
          {
            m_filterCoeffPrevSelected[varInd][i]=pcAlfParam->alfCoeffLuma[varInd][k];
            k++;
          }
          else
          {
            m_filterCoeffPrevSelected[varInd][i]=0;
          }
        }
      }
    }
  }
  else
  {
#endif
  if(pcAlfParam->filtNo>=0)
  {
    //// Reconstruct filter coefficients
    reconstructFilterCoeffs( pcAlfParam, pfilterCoeffSym, numBits);
  }
  else
  {
#if JVET_C0038_GALF
    for(i = 0; i < m_max_NO_VAR_BINS; i++)
#else
    for(i = 0; i < m_NO_VAR_BINS; i++)
#endif
    {
      pcAlfParam->varIndTab[i]=0;
      memset(pfilterCoeffSym[i],0,sizeof(int)*m_MAX_SQR_FILT_LENGTH);
    }
  }
  getCurrentFilter(pfilterCoeffSym,pcAlfParam);
#if COM16_C806_ALF_TEMPPRED_NUM
  }
#endif

  Int *coef;
  Int maxPxlVal = m_nIBDIMax;
#if JVET_C0038_GALF 
  Int flipTableSize;
  Int centerCoef = m_MAX_SQR_FILT_LENGTH - 1;
#else
  Int maxSampleValue, minSampleValue = 0;
  Int clipRange[2] = { 0, 0 }, flipTableSize;
  Int sumCoef[2];

  Int numBitsMinus1= m_NUM_BITS-1;
  Int offset = (1<<(m_NUM_BITS-2));
  Int lastCoef = m_MAX_SQR_FILT_LENGTH-1;
  Int centerCoef = m_MAX_SQR_FILT_LENGTH-2;
#endif

#if JVET_C0038_GALF
  for(Int varInd=0; varInd<m_max_NO_VAR_BINS; ++varInd)
  {
    coef = m_filterCoeffPrevSelected[varInd];
    for(i = 0; i < centerCoef; i++)
    {
      m_filterCoeffShort[varInd][i] = (Short)coef[i];
    }
    m_filterCoeffShort[varInd][centerCoef] = (Short)coef[centerCoef];
  }
#else
  for(Int varInd=0; varInd<m_NO_VAR_BINS; ++varInd)
  {
    coef = m_filterCoeffPrevSelected[varInd];
    sumCoef[0] = 0;
    sumCoef[1] = 0;
    for(i = 0; i < centerCoef; i++)
    {
      assert( coef[i]<=32767 && coef[i]>=-32768 );
      m_filterCoeffShort[varInd][i] = (Short)coef[i];
      sumCoef[ coef[i] > 0 ? 0 : 1 ] += (coef[i] << 1);
    }
    assert( coef[centerCoef]<=32767 && coef[centerCoef]>=-32768 );
    assert( coef[lastCoef]  <=32767 && coef[lastCoef]  >=-32768 );

    m_filterCoeffShort[varInd][centerCoef] = (Short)coef[centerCoef];
    m_filterCoeffShort[varInd][lastCoef]   = (Short)coef[lastCoef];

    sumCoef[ coef[centerCoef] > 0 ? 0 : 1 ] += coef[centerCoef];
    maxSampleValue = ( maxPxlVal * sumCoef[0] + coef[lastCoef] + offset ) >> numBitsMinus1;
    minSampleValue = ( maxPxlVal * sumCoef[1] + coef[lastCoef] + offset ) >> numBitsMinus1;

    if( clipRange[0] < maxSampleValue )
    {
      clipRange[0] = maxSampleValue;
    }
    if( clipRange[1] > minSampleValue )
    {
      clipRange[1] = minSampleValue;
    }
  }

  Int clipTableMax = ( ( m_ALF_HM3_QC_CLIP_RANGE - m_ALF_HM3_QC_CLIP_OFFSET - 1 ) << m_nBitIncrement );
  Int clipTableMin = ( ( - m_ALF_HM3_QC_CLIP_OFFSET ) << m_nBitIncrement );

  assert( clipRange[0]<=clipTableMax && clipRange[1]>=clipTableMin );
#endif


  flipTableSize   = (m_ALF_HM3_QC_CLIP_RANGE <<m_nBitIncrement);
  m_alfClipOffset = (m_ALF_HM3_QC_CLIP_OFFSET<<m_nBitIncrement);

  if( m_alfClipTable )
  {
    free(m_alfClipTable);
  }

  m_alfClipTable = (imgpel *)calloc(flipTableSize, sizeof(imgpel));

  for(Int k=0; k< flipTableSize; k++)
  {
    m_alfClipTable[k] = max( 0, min( k-m_alfClipOffset, maxPxlVal ) );
  }

  memset(m_imgY_temp[0],0,sizeof(int)*(m_ALF_WIN_VERSIZE+2*m_VAR_SIZE)*(m_ALF_WIN_HORSIZE+2*m_VAR_SIZE));
  m_imgY_var       = m_varImgMethods;
}


#if JVET_C0038_GALF
Void TComAdaptiveLoopFilter::getCurrentFilter(int **filterCoeffSym,ALFParam* pcAlfParam)
{
  int i,  k, varInd, filterNo;
  int *patternMap;
  int *patternMapTab[3]={m_pattern9x9Sym_Quart, m_pattern7x7Sym_Quart, m_pattern5x5Sym_Quart};
  
  Int ** filterCoeffFinal;
  Int factor = (1<<(TComAdaptiveLoopFilter::m_NUM_BITS-1)); 
  Int iMaxNumCoeff = (m_MAX_SQR_FILT_LENGTH/2+1);

  initMatrix_int(&filterCoeffFinal, m_max_NO_VAR_BINS, iMaxNumCoeff);
  
  for(varInd=0; varInd<m_max_NO_VAR_BINS; ++varInd)
  {
    memset(m_filterCoeffPrevSelected[varInd], 0, sizeof(int)*m_MAX_SQR_FILT_LENGTH);
    memset(filterCoeffFinal[varInd],          0, sizeof(int)*iMaxNumCoeff         );
  }

  if(pcAlfParam->iPredPattern)
  {
    for(varInd=0; varInd< m_max_NO_VAR_BINS; ++varInd)
    {
      if(pcAlfParam->PrevFiltIdx[varInd])
      {
        Int iPrevFiltIdx = pcAlfParam->PrevFiltIdx[varInd] - 1;
        for(i = 0; i < iMaxNumCoeff; i++)
        {
          filterNo = varInd*JVET_C0038_NO_PREV_FILTERS + iPrevFiltIdx;
          filterCoeffFinal[varInd][i] = m_ALFfilterCoeffFixed[filterNo][i]; 
        }
      }
      else
      {
        memset(filterCoeffFinal[varInd], 0, sizeof(Int)*(iMaxNumCoeff-1));
        filterCoeffFinal[varInd][iMaxNumCoeff-1] = factor;
      }
    }
  }
  else
  {
    for(varInd=0; varInd< m_max_NO_VAR_BINS; ++varInd)
    {
      memset(filterCoeffFinal[varInd], 0, (iMaxNumCoeff - 1)*sizeof(Int) );
      filterCoeffFinal[varInd][(iMaxNumCoeff - 1)] = factor;
    }
  }
  patternMap=patternMapTab[pcAlfParam->realfiltNo];

  for(varInd=0; varInd<m_max_NO_VAR_BINS; ++varInd)
  {
    k=0;
    for(i = 0; i < m_MAX_SQR_FILT_LENGTH; i++)
    {
      if (m_pattern9x9Sym_Quart[i] > 0 && patternMap[i]>0)
      {
        m_filterCoeffPrevSelected[varInd][i]= (filterCoeffFinal[varInd][m_pattern9x9Sym_Quart[i]-1]+ filterCoeffSym[pcAlfParam->varIndTab[varInd]][patternMap[i]-1]);
        pcAlfParam->alfCoeffLuma[varInd][m_pattern9x9Sym_Quart[i]-1] = m_filterCoeffPrevSelected[varInd][i];
        k++;
      }
      else if(m_pattern9x9Sym_Quart[i] > 0)
      {
        m_filterCoeffPrevSelected[varInd][i] = filterCoeffFinal[varInd][m_pattern9x9Sym_Quart[i]-1];
        pcAlfParam->alfCoeffLuma[varInd][m_pattern9x9Sym_Quart[i]-1]  = filterCoeffFinal[varInd][m_pattern9x9Sym_Quart[i]-1];
      }
      else
      {
        m_filterCoeffPrevSelected[varInd][i]=0;
      }
    }
  }
  Int iNumCoeffMinus1 = m_MAX_SQT_FILT_SYM_LENGTH - 1, quantCoeffSum = 0;
  Int * weights=TComAdaptiveLoopFilter::m_weightsTab[0];   

  for(varInd = 0; varInd < m_max_NO_VAR_BINS; ++ varInd)
  {
    quantCoeffSum = 0 ;
    for(i = 0; i < iNumCoeffMinus1; i++)
    {
      quantCoeffSum += weights[i]* pcAlfParam->alfCoeffLuma[varInd][i];
    }
    pcAlfParam->alfCoeffLuma [varInd][iNumCoeffMinus1] = factor-quantCoeffSum;
    m_filterCoeffPrevSelected[varInd][m_MAX_SQR_FILT_LENGTH - 1] = factor-quantCoeffSum;
  }
  destroyMatrix_int(filterCoeffFinal);
}
#else
Void TComAdaptiveLoopFilter::getCurrentFilter(int **filterCoeffSym,ALFParam* pcAlfParam)
{ 
  int i,  k, varInd;
  int *patternMap;
  int *patternMapTab[3]={m_pattern9x9Sym_Quart, m_pattern7x7Sym_Quart, m_pattern5x5Sym_Quart};
  {
    for(varInd=0; varInd<m_NO_VAR_BINS; ++varInd)
    {
      memset(m_filterCoeffPrevSelected[varInd],0,sizeof(int)*m_MAX_SQR_FILT_LENGTH);
    }
    patternMap=patternMapTab[pcAlfParam->realfiltNo];
    for(varInd=0; varInd<m_NO_VAR_BINS; ++varInd)
    {
      k=0;
      for(i = 0; i < m_MAX_SQR_FILT_LENGTH; i++)
      {
        if (patternMap[i]>0)
        {
          m_filterCoeffPrevSelected[varInd][i]=filterCoeffSym[pcAlfParam->varIndTab[varInd]][k];
#if COM16_C806_ALF_TEMPPRED_NUM
          pcAlfParam->alfCoeffLuma[varInd][k] = m_filterCoeffPrevSelected[varInd][i];
#endif
          k++;
        }
        else
        {
          m_filterCoeffPrevSelected[varInd][i]=0;
        }
      }
    }
  }
}
#endif

Void TComAdaptiveLoopFilter::reconstructFilterCoeffs(ALFParam* pcAlfParam,int **pfilterCoeffSym, int bit_depth)
{
  int i, src, ind;

  // Copy non zero filters in filterCoeffTmp
  for(ind = 0; ind < pcAlfParam->filters_per_group_diff; ++ind)
  {
    for(i = 0; i < pcAlfParam->num_coeff; i++)
      m_filterCoeffTmp[ind][i] = pcAlfParam->coeffmulti[ind][i];
  }
  // Undo prediction
  for(ind = 0; ind < pcAlfParam->filters_per_group_diff; ++ind)
  {
    if((!pcAlfParam->predMethod) || (ind == 0)) 
    {
      memcpy(m_filterCoeffSymTmp[ind],m_filterCoeffTmp[ind],sizeof(int)*pcAlfParam->num_coeff);
    }
    else
    {
      // Prediction
      for(i = 0; i < pcAlfParam->num_coeff; ++i)
        m_filterCoeffSymTmp[ind][i] = (int)(m_filterCoeffTmp[ind][i] + m_filterCoeffSymTmp[ind - 1][i]);
    }
  }
  // Inverse quantization
  // Add filters forced to zero
  if(pcAlfParam->forceCoeff0)
  {
#if !JVET_C0038_GALF
    assert(pcAlfParam->filters_per_group_diff < pcAlfParam->filters_per_group);
#endif
    src = 0;
    for(ind = 0; ind < pcAlfParam->filters_per_group; ++ind)
    {
      if(pcAlfParam->codedVarBins[ind])
      {
#if JVET_C0038_GALF
        memcpy(pfilterCoeffSym[ind],m_filterCoeffSymTmp[ind],sizeof(int)*pcAlfParam->num_coeff);
#else
        memcpy(pfilterCoeffSym[ind],m_filterCoeffSymTmp[src],sizeof(int)*pcAlfParam->num_coeff);
#endif
        ++src;
      }
      else
      {
        memset(pfilterCoeffSym[ind],0,sizeof(int)*pcAlfParam->num_coeff);
      }
    }
#if JVET_C0038_GALF
    pcAlfParam->filters_per_group_diff = src;
    assert(pcAlfParam->filters_per_group_diff < pcAlfParam->filters_per_group);
#else
    assert(src == pcAlfParam->filters_per_group_diff);
#endif
  }
  else
  {
    assert(pcAlfParam->filters_per_group_diff == pcAlfParam->filters_per_group);
    for(ind = 0; ind < pcAlfParam->filters_per_group; ++ind)
      memcpy(pfilterCoeffSym[ind],m_filterCoeffSymTmp[ind],sizeof(int)*pcAlfParam->num_coeff);
  }
}


static imgpel Clip_post(int high, int val)
{
  return (imgpel)(((val > high)? high: val));
}

Void TComAdaptiveLoopFilter::calcVar(imgpel **imgY_var, imgpel *imgY_pad, int pad_size, int fl, int img_height, int img_width, int img_stride, int start_width , int start_height )
{
  Int i, j;

  Int end_height = start_height + img_height;
  Int end_width  = start_width + img_width;
  for(i = start_height; i < end_height; i+=m_ALF_WIN_VERSIZE)
  {
    for(j = start_width; j < end_width; j+=m_ALF_WIN_HORSIZE) 
    {
      Int nHeight = min( i + m_ALF_WIN_VERSIZE, end_height ) - i;
      Int nWidth  = min( j + m_ALF_WIN_HORSIZE, end_width  ) - j;
      xCalcVar( imgY_var, imgY_pad, pad_size, fl, nHeight, nWidth, img_stride, j, i );
    }
  }
}
#if JVET_C0038_GALF
Void TComAdaptiveLoopFilter::xCalcVarPerPixel(imgpel **imgY_var, imgpel *imgY_pad, Int pad_size, Int fl, Int img_height, Int img_width, Int img_stride, Int start_width , Int start_height )
{
  Int th[16] = {0, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4};  
  fl              = 2;
  Int i, j;
#if FULL_NBIT
  Int shift= (11+ m_nBitIncrement + m_nInputBitDepth - 8);
#else
  Int shift= (11+ m_nBitIncrement);
#endif
  Int flplusOne = fl + 1;
  Int fl2plusTwo = 2*fl + 2; 
  Int var_max= 15;

  Int avg_var;
  Int mainDirection, secondaryDirection, dirTempHV, dirTempD;

  Int pixY; 
  Int iTempAct = 0;

  Int imgHExtended = img_height + fl2plusTwo;
  Int imgWExtended = img_width  + fl2plusTwo;
  Int start_height1 = start_height - flplusOne;

  for(i = 2; i < imgHExtended; i+=2)
  {
    Int yoffset = (i - 1 + start_height1) * img_stride - flplusOne;
    imgpel *p_imgY_pad_down = &imgY_pad[yoffset - img_stride  ];
    imgpel *p_imgY_pad      = &imgY_pad[yoffset               ];
    imgpel *p_imgY_pad_up   = &imgY_pad[yoffset + img_stride  ];
    imgpel *p_imgY_pad_up2  = &imgY_pad[yoffset + img_stride*2];
    for(j = 2; j < imgWExtended; j+=2)  
    {
      pixY = j - 1 + start_width;
      m_imgY_ver [i-2][j-2] = abs((p_imgY_pad   [pixY  ]<<1) - p_imgY_pad_down[pixY  ] - p_imgY_pad_up  [pixY  ])+   
                               abs((p_imgY_pad   [pixY+1]<<1) - p_imgY_pad_down[pixY+1] - p_imgY_pad_up  [pixY+1])+   
                               abs((p_imgY_pad_up[pixY  ]<<1) - p_imgY_pad     [pixY  ] - p_imgY_pad_up2 [pixY  ])+   
                               abs((p_imgY_pad_up[pixY+1]<<1) - p_imgY_pad     [pixY+1] - p_imgY_pad_up2 [pixY+1]);   

      m_imgY_hor [i-2][j-2] = abs((p_imgY_pad   [pixY  ]<<1) - p_imgY_pad     [pixY+1] - p_imgY_pad     [pixY-1])+        
                               abs((p_imgY_pad   [pixY+1]<<1) - p_imgY_pad     [pixY+2] - p_imgY_pad     [pixY  ])+        
                               abs((p_imgY_pad_up[pixY  ]<<1) - p_imgY_pad_up  [pixY+1] - p_imgY_pad_up  [pixY-1])+        
                               abs((p_imgY_pad_up[pixY+1]<<1) - p_imgY_pad_up  [pixY+2] - p_imgY_pad_up  [pixY  ]);        
      m_imgY_dig0[i-2][j-2] = abs((p_imgY_pad   [pixY  ]<<1) - p_imgY_pad_down[pixY-1] - p_imgY_pad_up  [pixY+1])+
                              abs((p_imgY_pad   [pixY+1]<<1) - p_imgY_pad_down[pixY  ] - p_imgY_pad_up  [pixY+2])+
                              abs((p_imgY_pad_up[pixY  ]<<1) - p_imgY_pad     [pixY-1] - p_imgY_pad_up2 [pixY+1])+
                              abs((p_imgY_pad_up[pixY+1]<<1) - p_imgY_pad     [pixY  ] - p_imgY_pad_up2 [pixY+2]);

      m_imgY_dig1[i-2][j-2] = abs((p_imgY_pad   [pixY  ]<<1) - p_imgY_pad_up  [pixY-1] - p_imgY_pad_down[pixY+1])+
                              abs((p_imgY_pad   [pixY+1]<<1) - p_imgY_pad_up  [pixY  ] - p_imgY_pad_down[pixY+2])+
                              abs((p_imgY_pad_up[pixY  ]<<1) - p_imgY_pad_up2 [pixY-1] - p_imgY_pad     [pixY+1])+
                              abs((p_imgY_pad_up[pixY+1]<<1) - p_imgY_pad_up2 [pixY  ] - p_imgY_pad     [pixY+2]);
      if (j > 4 )
      {
        m_imgY_ver [i-2][j-6] = m_imgY_ver [i-2][j-6]+m_imgY_ver [i-2][j-4]+m_imgY_ver [i-2][j-2];
        m_imgY_hor [i-2][j-6] = m_imgY_hor [i-2][j-6]+m_imgY_hor [i-2][j-4]+m_imgY_hor [i-2][j-2];
        m_imgY_dig0[i-2][j-6] = m_imgY_dig0[i-2][j-6]+m_imgY_dig0[i-2][j-4]+m_imgY_dig0[i-2][j-2];
        m_imgY_dig1[i-2][j-6] = m_imgY_dig1[i-2][j-6]+m_imgY_dig1[i-2][j-4]+m_imgY_dig1[i-2][j-2];
      }
    }
  }

  for(i = 0; i < img_height; i += 2)
  {
    for(j = 0; j < img_width; j += 2)  
    {
      Int sum_V   = m_imgY_ver [i][j] +m_imgY_ver [i+2][j]+m_imgY_ver [i+4][j];
      Int sum_H   = m_imgY_hor [i][j] +m_imgY_hor [i+2][j]+m_imgY_hor [i+4][j]; 
      Int sum_D0  = m_imgY_dig0[i][j] +m_imgY_dig0[i+2][j]+m_imgY_dig0[i+4][j];
      Int sum_D1  = m_imgY_dig1[i][j] +m_imgY_dig1[i+2][j]+m_imgY_dig1[i+4][j];
      iTempAct    = sum_V+sum_H;
      avg_var     = (imgpel) Clip_post(var_max, (iTempAct*24)>>(shift));     
      avg_var     = th[avg_var];
      Int HV_high, HV_low;
      Int D_high, D_low;
      Int HV_D_high, HV_D_low;
      if (sum_V>sum_H)
      {
        HV_high = sum_V;
        HV_low  = sum_H;
        dirTempHV=1;
      }
      else
      {
        HV_high = sum_H;
        HV_low  = sum_V;
        dirTempHV=3;
      }
      if (sum_D0 > sum_D1)
      {
        D_high = sum_D0;
        D_low  = sum_D1;
        dirTempD=0;
      }
      else
      {
        D_high = sum_D1;
        D_low  = sum_D0;
        dirTempD=2;
      }
      if ( D_high*HV_low > HV_high*D_low)
      {
        HV_D_high =  D_high;
        HV_D_low  =  D_low;
        mainDirection      = dirTempD;
        secondaryDirection = dirTempHV;
      }
      else
      {
        HV_D_high =  HV_high;
        HV_D_low  =  HV_low;
        mainDirection      = dirTempHV;
        secondaryDirection = dirTempD;
      }
      avg_var += ((2* (mainDirection) + (secondaryDirection)/2)<<NO_VALS_LAGR_SHIFT);
      if (HV_D_high > 2*HV_D_low)
      {
        avg_var += (8<<NO_VALS_LAGR_SHIFT);
      }
      if (HV_D_high*2 > 9*HV_D_low)
      {
        avg_var += (8<<NO_VALS_LAGR_SHIFT);
      }
      Int yOffset = (i + start_height);
      Int xOffset = (j + start_width );
      imgY_var[yOffset  ][xOffset  ] = imgY_var[yOffset  ][xOffset+1] = 
      imgY_var[yOffset+1][xOffset  ] = imgY_var[yOffset+1][xOffset+1] = avg_var;
    }
  }
}

Int TComAdaptiveLoopFilter::selectTransposeVarInd(Int varInd, Int *transpose)
{
    int aTransTable[8] ={0,1,0,2,2,3,1,3};
  int direction  = varInd>>NO_VALS_LAGR_SHIFT;
  int varIndMod  = varInd&((1<<NO_VALS_LAGR_SHIFT)-1);
  int dirRatio   = direction>>3;

  direction = direction&0x07;
  *transpose= aTransTable[direction];

  if (dirRatio)
  {
    varIndMod +=((direction&0x02)+dirRatio)*NO_VALS_LAGR;
  }
  return(varIndMod);
}

Void TComAdaptiveLoopFilter::xCalcVar(imgpel **imgY_var, imgpel *imgY_pad, int pad_size, int fl, int img_height, int img_width, int img_stride, int start_width , int start_height )
{
  xCalcVarPerPixel(imgY_var, imgY_pad, pad_size, fl, img_height, img_width, img_stride, start_width , start_height );
  return;
}
#else
Void TComAdaptiveLoopFilter::xCalcVar(imgpel **imgY_var, imgpel *imgY_pad, int pad_size, int fl, int img_height, int img_width, int img_stride, int start_width , int start_height )
{
  static Int shift_h     = (Int)(log((double)m_ALF_VAR_SIZE_H)/log(2.0));
  static Int shift_w     = (Int)(log((double)m_ALF_VAR_SIZE_W)/log(2.0));

  Int i, j;
  Int *p_imgY_temp;
#if FULL_NBIT
  Int shift= (11+ m_nBitIncrement + m_nInputBitDepth - 8);
#else
  Int shift= (11+ m_nBitIncrement);
#endif
  Int fl2plusOne= (m_VAR_SIZE<<1)+1; //3
  Int pad_offset = pad_size-fl-1;
  Int var_max= m_NO_VAR_BINS-1;
  Int mult_fact_int_tab[4]= {1,114,41,21};
  Int mult_fact_int = mult_fact_int_tab[m_VAR_SIZE];
  Int avg_var;
  Int vertical, horizontal;
  Int direction;
  Int step1 = m_NO_VAR_BINS/3 - 1;
  Int th[m_NO_VAR_BINS] = {0, 1, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4}; 
  Int pixY;

  for(i = 1; i < img_height + fl2plusOne; i++)
  {
    Int yoffset = (pad_offset+i+start_height-pad_size) * img_stride + pad_offset-pad_size;
    imgpel *p_imgY_pad = &imgY_pad[yoffset];
    imgpel *p_imgY_pad_up   = &imgY_pad[yoffset + img_stride];
    imgpel *p_imgY_pad_down = &imgY_pad[yoffset - img_stride];
    p_imgY_temp = (Int*)&m_imgY_temp[i-1][0];
    for(j = 1; j < img_width +fl2plusOne; j++)  
    {
      pixY = j + start_width;
      vertical = abs((p_imgY_pad[pixY]<<1) - p_imgY_pad_down[pixY] - p_imgY_pad_up[pixY]);
      horizontal = abs((p_imgY_pad[pixY]<<1) - p_imgY_pad[pixY+1] - p_imgY_pad[pixY-1]);
      m_imgY_ver[i-1][j-1] = vertical;
      m_imgY_hor[i-1][j-1] = horizontal;
      *(p_imgY_temp++) = vertical + horizontal;
    }

    for(j = 1; j < img_width + fl2plusOne; j=j+4)  
    {
      m_imgY_temp [i-1][j] =  (m_imgY_temp [i-1][j-1] + m_imgY_temp [i-1][j+4])
        + ((m_imgY_temp [i-1][j] + m_imgY_temp [i-1][j+3]) << 1)
        + ((m_imgY_temp [i-1][j+1] + m_imgY_temp [i-1][j+2]) * 3);
      m_imgY_ver[i-1][j] = m_imgY_ver[i-1][j] + m_imgY_ver[i-1][j+1] + m_imgY_ver[i-1][j+2] + m_imgY_ver[i-1][j+3];      
      m_imgY_hor[i-1][j] = m_imgY_hor[i-1][j] + m_imgY_hor[i-1][j+1] + m_imgY_hor[i-1][j+2] + m_imgY_hor[i-1][j+3];    
    }
  }

  for(i = 1; i < img_height + 1; i=i+4)
  {
    for(j = 1; j < img_width + 1; j=j+4)  
    {
      m_imgY_temp [i-1][j-1] =  (m_imgY_temp [i-1][j]+m_imgY_temp [i+4][j])
        + ((m_imgY_temp [i][j]+m_imgY_temp [i+3][j]) << 1)
        + ((m_imgY_temp [i+1][j]+m_imgY_temp [i+2][j]) * 3);

      m_imgY_ver[i-1][j-1] = m_imgY_ver[i][j] + m_imgY_ver[i+1][j] + m_imgY_ver[i+2][j] + m_imgY_ver[i+3][j];  
      m_imgY_hor[i-1][j-1] = m_imgY_hor[i][j] + m_imgY_hor[i+1][j] + m_imgY_hor[i+2][j] + m_imgY_hor[i+3][j];    
      avg_var = m_imgY_temp [i-1][j-1]>>(shift_h + shift_w);
      avg_var = (imgpel) Clip_post(var_max, (avg_var * mult_fact_int)>>shift);
      avg_var = th[avg_var];

      direction = 0;
      if (m_imgY_ver[i-1][j-1] > 2*m_imgY_hor[i-1][j-1]) direction = 1; //vertical
      if (m_imgY_hor[i-1][j-1] > 2*m_imgY_ver[i-1][j-1]) direction = 2; //horizontal

      avg_var = Clip_post(step1, (Int) avg_var ) + (step1+1)*direction; 
      imgY_var[(i + start_height - 1)>>shift_h][(j + start_width - 1)>>shift_w] = avg_var;
    }
  }
}
#endif

#if JVET_C0038_GALF
Void TComAdaptiveLoopFilter::filterFrame(imgpel *imgYRecPost, imgpel *imgYRec, ALFParam* pcAlfPara, int stride)
#else
Void TComAdaptiveLoopFilter::filterFrame(imgpel *imgYRecPost, imgpel *imgYRec, int filtNo, int stride)
#endif
{
  Int i, j;
  for (i = 0; i < m_img_height; i+=m_ALF_WIN_VERSIZE)
  {
    for (j = 0; j < m_img_width; j+=m_ALF_WIN_HORSIZE)
    {
      Int nHeight = min( i + m_ALF_WIN_VERSIZE, m_img_height ) - i;
      Int nWidth  = min( j + m_ALF_WIN_HORSIZE, m_img_width  ) - j;
#if JVET_C0038_GALF
      calcVar( m_imgY_var, imgYRec, m_FILTER_LENGTH/2, JVET_C0038_SHIFT_VAL_HALFW, nHeight, nWidth, stride , j , i);
      subfilterFrame(imgYRecPost, imgYRec, pcAlfPara, i, i + nHeight, j, j + nWidth, stride
               #if JVET_D0033_ADAPTIVE_CLIPPING
                    , COMPONENT_Y
               #endif
                     );
#else
      calcVar( m_imgY_var, imgYRec, m_FILTER_LENGTH/2, m_VAR_SIZE, nHeight, nWidth, stride , j , i );
      subfilterFrame(imgYRecPost, imgYRec, filtNo, i, i + nHeight, j, j + nWidth, stride
               #if JVET_D0033_ADAPTIVE_CLIPPING
                    , COMPONENT_Y
#endif
                     );
#endif
    }
  }
}
#if JVET_C0038_GALF
Void TComAdaptiveLoopFilter::subfilterFrame(imgpel *imgYRecPost, imgpel *imgYRec, ALFParam* pcAlfPara, Int startHeight, Int endHeight, Int startWidth, Int endWidth, Int stride,
                                            #if JVET_D0033_ADAPTIVE_CLIPPING
                                            ComponentID compid
#else
                                            Bool bChroma
                                            #endif
                                            )
#else
Void TComAdaptiveLoopFilter::subfilterFrame(imgpel *imgYRecPost, imgpel *imgYRec, int filtNo, int startHeight, int endHeight, int startWidth, int endWidth, int stride)
#endif
{
#if JVET_D0033_ADAPTIVE_CLIPPING
    const Bool bChroma=(compid!=COMPONENT_Y);
#endif
#if JVET_C0038_GALF
  if(bChroma)
  {
    assert(pcAlfPara->tap_chroma ==5);
  }
  Int filtNo = bChroma ? 2 : 0;
#else
  Int varStepSizeWidth = m_ALF_VAR_SIZE_W;
  Int varStepSizeHeight = m_ALF_VAR_SIZE_H;
  Int shiftHeight = (Int)(log((double)varStepSizeHeight)/log(2.0));
  Int shiftWidth = (Int)(log((double)varStepSizeWidth)/log(2.0));
#endif
  Int i, j, pixelInt;
  imgpel *pImgYVar,*pImgYPad;
  imgpel *pImgYPad1,*pImgYPad2,*pImgYPad3,*pImgYPad4,*pImgYPad5,*pImgYPad6;

  Short *coef = m_filterCoeffShort[0];
  imgpel *pImg0, *pImg1, *pImg2, *pImg3, *pImg4, *pImg5, *pImg6;
  imgpel *pImgYRec;
#if JVET_C0038_GALF
  imgpel *pImgYPad7, *pImgYPad8;
#endif
  imgpel *pClipTable = m_alfClipTable + m_alfClipOffset;

  Int numBitsMinus1= m_NUM_BITS-1;
  Int offset = (1<<(m_NUM_BITS-2));
#if JVET_C0038_GALF
  if(bChroma)
  {
    pImgYVar = NULL;
  }
  Int transpose = 0;
#endif
  
  imgYRecPost += startHeight*stride;

  switch(filtNo)
  {
  case 2:
    for (i =  startHeight; i < endHeight; i++)
    {
#if JVET_C0038_GALF
      if(!bChroma)
      {
        pImgYVar = m_imgY_var[i] + startWidth;
      }
#else
      pImgYVar = m_imgY_var[i>>shiftHeight] + (startWidth>>shiftWidth);
#endif
      pImgYPad = imgYRec + i*stride;
      pImgYPad1 = imgYRec + (i+1)*stride;
      pImgYPad2 = imgYRec + (i-1)*stride;
      pImgYPad3 = imgYRec + (i+2)*stride;
      pImgYPad4 = imgYRec + (i-2)*stride;

      pImgYRec = imgYRecPost + startWidth;

      for (j = startWidth; j < endWidth; j++)
      {
#if JVET_C0038_GALF
        if(!bChroma)
        {
          Int varIndMod = selectTransposeVarInd(*(pImgYVar++), &transpose);
          coef = m_filterCoeffShort[varIndMod];
        }
        pixelInt= 0;
#else
        if ((j&(varStepSizeWidth-1))==0) coef = m_filterCoeffShort[*(pImgYVar++)];
        pixelInt = coef[m_MAX_SQR_FILT_LENGTH-1];
#endif
        pImg0 = pImgYPad  + j;
        pImg1 = pImgYPad1 + j;
        pImg2 = pImgYPad2 + j;
        pImg3 = pImgYPad3 + j;
        pImg4 = pImgYPad4 + j;
#if JVET_C0038_GALF
        if(transpose==1)
        {
          pixelInt += coef[38]* (pImg3[+0]+pImg4[+0]);

          pixelInt += coef[30]* (pImg1[+1]+pImg2[-1]);
          pixelInt += coef[39]* (pImg1[+0]+pImg2[+0]);
          pixelInt += coef[32]* (pImg1[-1]+pImg2[+1]);

          pixelInt += coef[22]* (pImg0[-2]+pImg0[+2]);
          pixelInt += coef[31]* (pImg0[-1]+pImg0[+1]);
          pixelInt += coef[40]* (pImg0[+0]);          
        }
        else if(transpose == 3)
        {
          pixelInt += coef[38]* (pImg3[+0]+pImg4[+0]);

          pixelInt += coef[32]* (pImg1[+1]+pImg2[-1]);
          pixelInt += coef[39]* (pImg1[+0]+pImg2[+0]);
          pixelInt += coef[30]* (pImg1[-1]+pImg2[+1]);

          pixelInt += coef[22]* (pImg0[-2]+pImg0[+2]);
          pixelInt += coef[31]* (pImg0[-1]+pImg0[+1]);
          pixelInt += coef[40]* (pImg0[+0]);
        }
        else if(transpose == 2)
        {
          pixelInt += coef[22]* (pImg3[+0]+pImg4[+0]);

          pixelInt += coef[32]* (pImg1[+1]+pImg2[-1]);
          pixelInt += coef[31]* (pImg1[+0]+pImg2[+0]);
          pixelInt += coef[30]* (pImg1[-1]+pImg2[+1]);

          pixelInt += coef[38]* (pImg0[-2]+pImg0[+2]);
          pixelInt += coef[39]* (pImg0[-1]+pImg0[+1]);
          pixelInt += coef[40]* (pImg0[+0]);
        }
        else
        {
          pixelInt += coef[22]* (pImg3[+0]+pImg4[+0]);

          pixelInt += coef[30]* (pImg1[+1]+pImg2[-1]);
          pixelInt += coef[31]* (pImg1[+0]+pImg2[+0]);
          pixelInt += coef[32]* (pImg1[-1]+pImg2[+1]);

          pixelInt += coef[38]* (pImg0[-2]+pImg0[+2]);
          pixelInt += coef[39]* (pImg0[-1]+pImg0[+1]);
          pixelInt += coef[40]* (pImg0[+0]);
        }
#else

        pixelInt += coef[22]* (pImg3[+0]+pImg4[+0]);

        pixelInt += coef[30]* (pImg1[+1]+pImg2[-1]);
        pixelInt += coef[31]* (pImg1[+0]+pImg2[+0]);
        pixelInt += coef[32]* (pImg1[-1]+pImg2[+1]);

        pixelInt += coef[38]* (pImg0[-2]+pImg0[+2]);
        pixelInt += coef[39]* (pImg0[-1]+pImg0[+1]);
        pixelInt += coef[40]* (pImg0[+0]);
#endif
        pixelInt=(Int)((pixelInt+offset) >> (numBitsMinus1));
#if JVET_D0033_ADAPTIVE_CLIPPING // done here instead of inside the table TODO
        *(pImgYRec++) = ClipA(pClipTable[pixelInt],compid);
#else
        *(pImgYRec++) = pClipTable[pixelInt];
#endif
      }
      imgYRecPost += stride;
    }
    break;

  case 1:
    for (i =  startHeight; i < endHeight; i++)
    {
#if JVET_C0038_GALF
      if(!bChroma)
      {
        pImgYVar = m_imgY_var[i] + startWidth;
      }
#else
      pImgYVar = m_imgY_var[i>>shiftHeight] + (startWidth>>shiftWidth);
#endif
      pImgYPad = imgYRec + i*stride;
      pImgYPad1 = imgYRec + (i+1)*stride;
      pImgYPad2 = imgYRec + (i-1)*stride;
      pImgYPad3 = imgYRec + (i+2)*stride;
      pImgYPad4 = imgYRec + (i-2)*stride;
      pImgYPad5 = imgYRec + (i+3)*stride;
      pImgYPad6 = imgYRec + (i-3)*stride;

      pImgYRec = imgYRecPost + startWidth;

      for (j = startWidth; j < endWidth; j++)
      {
#if JVET_C0038_GALF
        if(!bChroma)
        {
          Int varIndMod = selectTransposeVarInd(*(pImgYVar++), &transpose);
          coef = m_filterCoeffShort[varIndMod];
        }
        pixelInt= 0;
#else
        if ((j&(varStepSizeWidth-1))==0) coef = m_filterCoeffShort[*(pImgYVar++)];
        pixelInt = coef[m_MAX_SQR_FILT_LENGTH-1];
#endif
        pImg0 = pImgYPad  + j;
        pImg1 = pImgYPad1 + j;
        pImg2 = pImgYPad2 + j;
        pImg3 = pImgYPad3 + j;
        pImg4 = pImgYPad4 + j;
        pImg5 = pImgYPad5 + j;
        pImg6 = pImgYPad6 + j;
#if JVET_C0038_GALF
        if(transpose == 1)
        {
          pixelInt += coef[37]* (pImg5[0]+pImg6[0]);

          pixelInt += coef[29]* (pImg3[+1]+pImg4[-1]);
          pixelInt += coef[38]* (pImg3[+0]+pImg4[+0]);
          pixelInt += coef[33]* (pImg3[-1]+pImg4[+1]);

          pixelInt += coef[21]* (pImg1[+2]+pImg2[-2]);
          pixelInt += coef[30]* (pImg1[+1]+pImg2[-1]);
          pixelInt += coef[39]* (pImg1[+0]+pImg2[+0]);
          pixelInt += coef[32]* (pImg1[-1]+pImg2[+1]);
          pixelInt += coef[23]* (pImg1[-2]+pImg2[+2]);

          pixelInt += coef[13]* (pImg0[+3]+pImg0[-3]);
          pixelInt += coef[22]* (pImg0[+2]+pImg0[-2]);
          pixelInt += coef[31]* (pImg0[+1]+pImg0[-1]);
          pixelInt += coef[40]* (pImg0[+0]);
        }
        else if(transpose == 3)
        {
          pixelInt += coef[37]* (pImg5[0]+pImg6[0]);

          pixelInt += coef[33]* (pImg3[+1]+pImg4[-1]);
          pixelInt += coef[38]* (pImg3[+0]+pImg4[+0]);
          pixelInt += coef[29]* (pImg3[-1]+pImg4[+1]);

          pixelInt += coef[23]* (pImg1[+2]+pImg2[-2]);
          pixelInt += coef[32]* (pImg1[+1]+pImg2[-1]);
          pixelInt += coef[39]* (pImg1[+0]+pImg2[+0]);
          pixelInt += coef[30]* (pImg1[-1]+pImg2[+1]);
          pixelInt += coef[21]* (pImg1[-2]+pImg2[+2]);

          pixelInt += coef[13]* (pImg0[+3]+pImg0[-3]);
          pixelInt += coef[22]* (pImg0[+2]+pImg0[-2]);
          pixelInt += coef[31]* (pImg0[+1]+pImg0[-1]);
          pixelInt += coef[40]* (pImg0[+0]);
        }
        else if(transpose == 2)
        {
          pixelInt += coef[13]* (pImg5[0]+pImg6[0]);

          pixelInt += coef[23]* (pImg3[+1]+pImg4[-1]);
          pixelInt += coef[22]* (pImg3[+0]+pImg4[+0]);
          pixelInt += coef[21]* (pImg3[-1]+pImg4[+1]);

          pixelInt += coef[33]* (pImg1[+2]+pImg2[-2]);
          pixelInt += coef[32]* (pImg1[+1]+pImg2[-1]);
          pixelInt += coef[31]* (pImg1[+0]+pImg2[+0]);
          pixelInt += coef[30]* (pImg1[-1]+pImg2[+1]);
          pixelInt += coef[29]* (pImg1[-2]+pImg2[+2]);

          pixelInt += coef[37]* (pImg0[+3]+pImg0[-3]);
          pixelInt += coef[38]* (pImg0[+2]+pImg0[-2]);
          pixelInt += coef[39]* (pImg0[+1]+pImg0[-1]);
          pixelInt += coef[40]* (pImg0[+0]);
        }
        else
        {
          pixelInt += coef[13]* (pImg5[0]+pImg6[0]);

          pixelInt += coef[21]* (pImg3[+1]+pImg4[-1]);
          pixelInt += coef[22]* (pImg3[+0]+pImg4[+0]);
          pixelInt += coef[23]* (pImg3[-1]+pImg4[+1]);

          pixelInt += coef[29]* (pImg1[+2]+pImg2[-2]);
          pixelInt += coef[30]* (pImg1[+1]+pImg2[-1]);
          pixelInt += coef[31]* (pImg1[+0]+pImg2[+0]);
          pixelInt += coef[32]* (pImg1[-1]+pImg2[+1]);
          pixelInt += coef[33]* (pImg1[-2]+pImg2[+2]);

          pixelInt += coef[37]* (pImg0[+3]+pImg0[-3]);
          pixelInt += coef[38]* (pImg0[+2]+pImg0[-2]);
          pixelInt += coef[39]* (pImg0[+1]+pImg0[-1]);
          pixelInt += coef[40]* (pImg0[+0]);
        }
#else
        pixelInt += coef[13]* (pImg5[0]+pImg6[0]);

        pixelInt += coef[21]* (pImg3[+1]+pImg4[-1]);
        pixelInt += coef[22]* (pImg3[+0]+pImg4[+0]);
        pixelInt += coef[23]* (pImg3[-1]+pImg4[+1]);

        pixelInt += coef[29]* (pImg1[+2]+pImg2[-2]);
        pixelInt += coef[30]* (pImg1[+1]+pImg2[-1]);
        pixelInt += coef[31]* (pImg1[+0]+pImg2[+0]);
        pixelInt += coef[32]* (pImg1[-1]+pImg2[+1]);
        pixelInt += coef[33]* (pImg1[-2]+pImg2[+2]);

        pixelInt += coef[37]* (pImg0[+3]+pImg0[-3]);
        pixelInt += coef[38]* (pImg0[+2]+pImg0[-2]);
        pixelInt += coef[39]* (pImg0[+1]+pImg0[-1]);
        pixelInt += coef[40]* (pImg0[+0]);
#endif

        pixelInt=(Int)((pixelInt+offset) >> (numBitsMinus1));
#if JVET_D0033_ADAPTIVE_CLIPPING // done here instead of inside the table TODO
        *(pImgYRec++) = ClipA(pClipTable[pixelInt],compid);
#else
        *(pImgYRec++) = pClipTable[pixelInt];
#endif
      }
      imgYRecPost += stride;
    }
    break;

  case 0:
    for (i =  startHeight; i < endHeight; i++)
    {
#if JVET_C0038_GALF
      if(!bChroma)
      {
        pImgYVar = m_imgY_var[i] + startWidth;
      }
#else
      pImgYVar = m_imgY_var[i>>shiftHeight] + (startWidth>>shiftWidth);
#endif
      pImgYPad = imgYRec + i*stride;
      pImgYPad1 = imgYRec + (i+1)*stride;
      pImgYPad2 = imgYRec + (i-1)*stride;
      pImgYPad3 = imgYRec + (i+2)*stride;
      pImgYPad4 = imgYRec + (i-2)*stride;
      pImgYPad5 = imgYRec + (i+3)*stride;
      pImgYPad6 = imgYRec + (i-3)*stride;
#if JVET_C0038_GALF
      pImgYPad7 = imgYRec + (i+4)*stride;
      pImgYPad8 = imgYRec + (i-4)*stride;
#endif
      pImgYRec = imgYRecPost + startWidth;

      for (j = startWidth; j < endWidth; j++)
      {
#if JVET_C0038_GALF
        if(!bChroma)
        {
          Int varIndMod = selectTransposeVarInd(*(pImgYVar++), &transpose);
          coef = m_filterCoeffShort[varIndMod];
        }
        pixelInt= 0;
#else
        if ((j&(varStepSizeWidth-1))==0) coef = m_filterCoeffShort[*(pImgYVar++)];
        pixelInt = coef[m_MAX_SQR_FILT_LENGTH-1];
#endif
        pImg0 = pImgYPad  + j;
        pImg1 = pImgYPad1 + j;
        pImg2 = pImgYPad2 + j;
        pImg3 = pImgYPad3 + j;
        pImg4 = pImgYPad4 + j;
        pImg5 = pImgYPad5 + j;
        pImg6 = pImgYPad6 + j;
#if JVET_C0038_GALF
        if(transpose == 1)
        {
          pixelInt += coef[36]* (pImgYPad7[j] + pImgYPad8[j]);
          pixelInt += coef[28]* (pImg5[1]+pImg6[-1]);
          pixelInt += coef[37]* (pImg5[0]+pImg6[0]);
          pixelInt += coef[34]* (pImg5[-1]+pImg6[1]);

          pixelInt += coef[20]* (pImg3[2]+pImg4[-2]);
          pixelInt += coef[29]* (pImg3[1]+pImg4[-1]);
          pixelInt += coef[38]* (pImg3[0]+pImg4[0]);
          pixelInt += coef[33]* (pImg3[-1]+pImg4[+1]);
          pixelInt += coef[24]* (pImg3[-2]+pImg4[+2]);

          pixelInt += coef[12]* (pImg1[3]+pImg2[-3]);
          pixelInt += coef[21]* (pImg1[2]+pImg2[-2]);
          pixelInt += coef[30]* (pImg1[1]+pImg2[-1]);
          pixelInt += coef[39]* (pImg1[0]+pImg2[0]);
          pixelInt += coef[32]* (pImg1[-1]+pImg2[+1]);
          pixelInt += coef[23]* (pImg1[-2]+pImg2[+2]);
          pixelInt += coef[14]* (pImg1[-3]+pImg2[+3]);

          pixelInt += coef[ 4]* (pImg0[+4]+pImg0[-4]);
          pixelInt += coef[13]* (pImg0[+3]+pImg0[-3]);
          pixelInt += coef[22]* (pImg0[+2]+pImg0[-2]);
          pixelInt += coef[31]* (pImg0[+1]+pImg0[-1]);
          pixelInt += coef[40]* (pImg0[0]);
        }
        else if(transpose == 3)
        {
          pixelInt += coef[36]* (pImgYPad7[j] + pImgYPad8[j]);
          pixelInt += coef[34]* (pImg5[1]+pImg6[-1]);
          pixelInt += coef[37]* (pImg5[0]+pImg6[0]);
          pixelInt += coef[28]* (pImg5[-1]+pImg6[1]);

          pixelInt += coef[24]* (pImg3[2]+pImg4[-2]);
          pixelInt += coef[33]* (pImg3[1]+pImg4[-1]);
          pixelInt += coef[38]* (pImg3[0]+pImg4[0]);
          pixelInt += coef[29]* (pImg3[-1]+pImg4[+1]);
          pixelInt += coef[20]* (pImg3[-2]+pImg4[+2]);

          pixelInt += coef[14]* (pImg1[3]+pImg2[-3]);
          pixelInt += coef[23]* (pImg1[2]+pImg2[-2]);
          pixelInt += coef[32]* (pImg1[1]+pImg2[-1]);
          pixelInt += coef[39]* (pImg1[0]+pImg2[0]);
          pixelInt += coef[30]* (pImg1[-1]+pImg2[+1]);
          pixelInt += coef[21]* (pImg1[-2]+pImg2[+2]);
          pixelInt += coef[12]* (pImg1[-3]+pImg2[+3]);

          pixelInt += coef[ 4]* (pImg0[+4]+pImg0[-4]);
          pixelInt += coef[13]* (pImg0[+3]+pImg0[-3]);
          pixelInt += coef[22]* (pImg0[+2]+pImg0[-2]);
          pixelInt += coef[31]* (pImg0[+1]+pImg0[-1]);
          pixelInt += coef[40]* (pImg0[0]);
        }
        else if(transpose == 2)
        {
          pixelInt += coef[4]* (pImgYPad7[j] + pImgYPad8[j]);
          pixelInt += coef[14]* (pImg5[1]+pImg6[-1]);
          pixelInt += coef[13]* (pImg5[0]+pImg6[0]);
          pixelInt += coef[12]* (pImg5[-1]+pImg6[1]);

          pixelInt += coef[24]* (pImg3[2]+pImg4[-2]);
          pixelInt += coef[23]* (pImg3[1]+pImg4[-1]);
          pixelInt += coef[22]* (pImg3[0]+pImg4[0]);
          pixelInt += coef[21]* (pImg3[-1]+pImg4[+1]);
          pixelInt += coef[20]* (pImg3[-2]+pImg4[+2]);

          pixelInt += coef[34]* (pImg1[3]+pImg2[-3]);
          pixelInt += coef[33]* (pImg1[2]+pImg2[-2]);
          pixelInt += coef[32]* (pImg1[1]+pImg2[-1]);
          pixelInt += coef[31]* (pImg1[0]+pImg2[0]);
          pixelInt += coef[30]* (pImg1[-1]+pImg2[+1]);
          pixelInt += coef[29]* (pImg1[-2]+pImg2[+2]);
          pixelInt += coef[28]* (pImg1[-3]+pImg2[+3]);

          pixelInt += coef[36]* (pImg0[+4]+pImg0[-4]);
          pixelInt += coef[37]* (pImg0[+3]+pImg0[-3]);
          pixelInt += coef[38]* (pImg0[+2]+pImg0[-2]);
          pixelInt += coef[39]* (pImg0[+1]+pImg0[-1]);
          pixelInt += coef[40]* (pImg0[0]);
        }
        else
        {
          pixelInt += coef[4]* (pImgYPad7[j] + pImgYPad8[j]);
          pixelInt += coef[12]* (pImg5[1]+pImg6[-1]);
          pixelInt += coef[13]* (pImg5[0]+pImg6[0]);
          pixelInt += coef[14]* (pImg5[-1]+pImg6[1]);

          pixelInt += coef[20]* (pImg3[2]+pImg4[-2]);
          pixelInt += coef[21]* (pImg3[1]+pImg4[-1]);
          pixelInt += coef[22]* (pImg3[0]+pImg4[0]);
          pixelInt += coef[23]* (pImg3[-1]+pImg4[+1]);
          pixelInt += coef[24]* (pImg3[-2]+pImg4[+2]);

          pixelInt += coef[28]* (pImg1[3]+pImg2[-3]);
          pixelInt += coef[29]* (pImg1[2]+pImg2[-2]);
          pixelInt += coef[30]* (pImg1[1]+pImg2[-1]);
          pixelInt += coef[31]* (pImg1[0]+pImg2[0]);
          pixelInt += coef[32]* (pImg1[-1]+pImg2[+1]);
          pixelInt += coef[33]* (pImg1[-2]+pImg2[+2]);
          pixelInt += coef[34]* (pImg1[-3]+pImg2[+3]);

          pixelInt += coef[36]* (pImg0[+4]+pImg0[-4]);
          pixelInt += coef[37]* (pImg0[+3]+pImg0[-3]);
          pixelInt += coef[38]* (pImg0[+2]+pImg0[-2]);
          pixelInt += coef[39]* (pImg0[+1]+pImg0[-1]);
          pixelInt += coef[40]* (pImg0[0]);
        }
#else
        pixelInt += coef[12]* (pImg5[1]+pImg6[-1]);
        pixelInt += coef[13]* (pImg5[0]+pImg6[0]);
        pixelInt += coef[14]* (pImg5[-1]+pImg6[1]);

        pixelInt += coef[20]* (pImg3[2]+pImg4[-2]);
        pixelInt += coef[21]* (pImg3[1]+pImg4[-1]);
        pixelInt += coef[22]* (pImg3[0]+pImg4[0]);
        pixelInt += coef[23]* (pImg3[-1]+pImg4[+1]);
        pixelInt += coef[24]* (pImg3[-2]+pImg4[+2]);

        pixelInt += coef[28]* (pImg1[3]+pImg2[-3]);
        pixelInt += coef[29]* (pImg1[2]+pImg2[-2]);
        pixelInt += coef[30]* (pImg1[1]+pImg2[-1]);
        pixelInt += coef[31]* (pImg1[0]+pImg2[0]);
        pixelInt += coef[32]* (pImg1[-1]+pImg2[+1]);
        pixelInt += coef[33]* (pImg1[-2]+pImg2[+2]);
        pixelInt += coef[34]* (pImg1[-3]+pImg2[+3]);

        pixelInt += coef[36]* (pImg0[+4]+pImg0[-4]);
        pixelInt += coef[37]* (pImg0[+3]+pImg0[-3]);
        pixelInt += coef[38]* (pImg0[+2]+pImg0[-2]);
        pixelInt += coef[39]* (pImg0[+1]+pImg0[-1]);
        pixelInt += coef[40]* (pImg0[0]);
#endif
        pixelInt=(Int)((pixelInt+offset) >> (numBitsMinus1));

#if JVET_D0033_ADAPTIVE_CLIPPING // done here instead of inside the table TODO
        *(pImgYRec++) = ClipA(pClipTable[pixelInt],compid);
#else
        *(pImgYRec++) = pClipTable[pixelInt];
#endif
      }
      imgYRecPost += stride;
    }
    break;
  }
}


Void TComAdaptiveLoopFilter::xCUAdaptive_qc(TComPic* pcPic, ALFParam* pcAlfParam, imgpel *imgY_rec_post, imgpel *imgY_rec, Int Stride)
{
  // for every CU, call CU-adaptive ALF process
  for( UInt uiCUAddr = 0; uiCUAddr < pcPic->getNumberOfCtusInFrame() ; uiCUAddr++ )
  {
    TComDataCU* pcCU = pcPic->getCtu( uiCUAddr );
#if JVET_C0024_QTBT
    xSubCUAdaptive_qc(pcCU, pcAlfParam, imgY_rec_post, imgY_rec, 0, 0, pcCU->getSlice()->getSPS()->getCTUSize(), pcCU->getSlice()->getSPS()->getCTUSize(), Stride);
#else
    xSubCUAdaptive_qc(pcCU, pcAlfParam, imgY_rec_post, imgY_rec, 0, 0, Stride);
#endif
  }
}

#if JVET_C0024_QTBT
Void TComAdaptiveLoopFilter::xSubCUAdaptive_qc(TComDataCU* pcCU, ALFParam* pcAlfParam, imgpel *imgY_rec_post, imgpel *imgY_rec, UInt uiAbsPartIdx, UInt uiDepth, UInt uiWidth, UInt uiHeight, Int Stride)
#else
Void TComAdaptiveLoopFilter::xSubCUAdaptive_qc(TComDataCU* pcCU, ALFParam* pcAlfParam, imgpel *imgY_rec_post, imgpel *imgY_rec, UInt uiAbsPartIdx, UInt uiDepth, Int Stride)
#endif
{
  TComPic* pcPic = pcCU->getPic();
  
#if !JVET_C0024_QTBT
  Bool bBoundary = false;
#endif
  UInt uiLPelX   = pcCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[uiAbsPartIdx] ];
#if JVET_C0024_QTBT
  UInt uiRPelX   = uiLPelX + uiWidth  - 1;
#else
  UInt uiRPelX   = uiLPelX + (pcCU->getSlice()->getSPS()->getMaxCUWidth()>>uiDepth)  - 1;
#endif
  UInt uiTPelY   = pcCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[uiAbsPartIdx] ];
#if JVET_C0024_QTBT
  UInt uiBPelY   = uiTPelY + uiHeight - 1;
#else
  UInt uiBPelY   = uiTPelY + (pcCU->getSlice()->getSPS()->getMaxCUHeight() >>uiDepth) - 1;
#endif
  
#if !JVET_C0024_QTBT
  // check picture boundary
  if ( ( uiRPelX >= pcCU->getSlice()->getSPS()->getPicWidthInLumaSamples() ) || ( uiBPelY >= pcCU->getSlice()->getSPS()->getPicHeightInLumaSamples() ) )
  {
    bBoundary = true;
  }
#endif
  
  // go to sub-CU?
#if JVET_C0024_QTBT
  if ( uiDepth < pcCU->getDepth( uiAbsPartIdx ) && uiDepth < pcAlfParam->alf_max_depth  )
#else
  if ( ( ( uiDepth < pcCU->getDepth( uiAbsPartIdx ) ) && ( uiDepth < pcCU->getSlice()->getSPS()->getLog2DiffMaxMinCodingBlockSize() ) && uiDepth < pcAlfParam->alf_max_depth ) || bBoundary )
#endif
  {
    UInt uiQNumParts = ( pcPic->getNumPartitionsInCtu() >> (uiDepth<<1) )>>2;
    for ( UInt uiPartUnitIdx = 0; uiPartUnitIdx < 4; uiPartUnitIdx++, uiAbsPartIdx+=uiQNumParts )
    {
      uiLPelX   = pcCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[uiAbsPartIdx] ];
      uiTPelY   = pcCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[uiAbsPartIdx] ];
      
      if( ( uiLPelX < pcCU->getSlice()->getSPS()->getPicWidthInLumaSamples() ) && ( uiTPelY < pcCU->getSlice()->getSPS()->getPicHeightInLumaSamples() ) )
#if JVET_C0024_QTBT
        xSubCUAdaptive_qc(pcCU, pcAlfParam, imgY_rec_post, imgY_rec, uiAbsPartIdx, uiDepth+1, uiWidth>>1, uiHeight>>1, Stride);
#else
        xSubCUAdaptive_qc(pcCU, pcAlfParam, imgY_rec_post, imgY_rec, uiAbsPartIdx, uiDepth+1, Stride);
#endif
    }
    return;
  }
  
#if JVET_C0024_QTBT
  if( uiRPelX >= pcCU->getSlice()->getSPS()->getPicWidthInLumaSamples() )
  {
    //bBoundary = true;
    uiWidth = pcCU->getSlice()->getSPS()->getPicWidthInLumaSamples() - uiLPelX;
    uiRPelX = pcCU->getSlice()->getSPS()->getPicWidthInLumaSamples() - 1;
  }
  if ( uiBPelY >= pcCU->getSlice()->getSPS()->getPicHeightInLumaSamples() )
  {
    //  bBoundary = true;
      uiHeight = pcCU->getSlice()->getSPS()->getPicHeightInLumaSamples() - uiTPelY;
      uiBPelY = pcCU->getSlice()->getSPS()->getPicHeightInLumaSamples() - 1;
  }
#endif
  // check maskImagedec
  if ( pcCU->getAlfCtrlFlag(uiAbsPartIdx) )
  {
#if JVET_C0024_QTBT&&!JVET_C0038_GALF
    calcVar( m_imgY_var, imgY_rec, m_FILTER_LENGTH/2, m_VAR_SIZE, uiHeight, uiWidth, Stride , uiLPelX , uiTPelY );
    subfilterFrame(imgY_rec_post, imgY_rec, pcAlfParam->realfiltNo, uiTPelY, uiBPelY+1, uiLPelX, uiRPelX+1, Stride
               #if JVET_D0033_ADAPTIVE_CLIPPING
                    , COMPONENT_Y
               #endif
                   );
#else
    Int nHeight = min(uiBPelY+1,(unsigned int)(m_img_height)) - uiTPelY;
    Int nWidth  = min(uiRPelX+1,(unsigned int)(m_img_width)) - uiLPelX;
#if JVET_C0038_GALF
    calcVar( m_imgY_var, imgY_rec, m_FILTER_LENGTH/2, JVET_C0038_SHIFT_VAL_HALFW, nHeight, nWidth, Stride , uiLPelX , uiTPelY);
    subfilterFrame(imgY_rec_post, imgY_rec, pcAlfParam, uiTPelY, min(uiBPelY+1,(unsigned int)(m_img_height)), uiLPelX, min(uiRPelX+1,(unsigned int)(m_img_width)), Stride
               #if JVET_D0033_ADAPTIVE_CLIPPING
                    , COMPONENT_Y
               #endif
                   );
#else
    calcVar( m_imgY_var, imgY_rec, m_FILTER_LENGTH/2, m_VAR_SIZE, nHeight, nWidth, Stride , uiLPelX , uiTPelY );
    subfilterFrame(imgY_rec_post, imgY_rec, pcAlfParam->realfiltNo, uiTPelY, min(uiBPelY+1,(unsigned int)(m_img_height)), uiLPelX, min(uiRPelX+1,(unsigned int)(m_img_width)), Stride
               #if JVET_D0033_ADAPTIVE_CLIPPING
                    , COMPONENT_Y
#endif
                   );
#endif
#endif
  }
  else
  {
    // copy to rec
    Int nOffset = uiTPelY * Stride + uiLPelX;
    imgpel * pSrc = imgY_rec + nOffset;
    imgpel * pDst = imgY_rec_post + nOffset;
#if JVET_C0024_QTBT
    Int nSize = uiWidth * sizeof(imgpel);
    for (Int n=0; n<uiHeight; n++)
#else
    Int nHeight = min(uiBPelY+1,(unsigned int)(m_img_height)) - uiTPelY;
    Int nWidth  = min(uiRPelX+1,(unsigned int)(m_img_width)) - uiLPelX;
    Int nSize = nWidth * sizeof( imgpel );
    for( Int n = 0 ; n < nHeight ; n++ )
#endif
    {
      memcpy( pDst , pSrc , nSize );
      pSrc += Stride;
      pDst += Stride;
    }
  }
}

// --------------------------------------------------------------------------------------------------------------------
// ALF for chroma
// --------------------------------------------------------------------------------------------------------------------

Void TComAdaptiveLoopFilter::xALFChroma(ALFParam* pcAlfParam, TComPicYuv* pcPicDec, TComPicYuv* pcPicRest)
{
  if((pcAlfParam->chroma_idc>>1)&0x01)
  {
#if JVET_C0038_GALF
    xFrameChroma( pcAlfParam, pcPicDec, pcPicRest, 0 );
#else
    xFrameChroma(pcPicDec, pcPicRest, pcAlfParam->coeff_chroma, pcAlfParam->tap_chroma, 0);
#endif
  }
  else
  {
    pcPicDec->copyToPic( pcPicRest , COMPONENT_Cb , false );
  }
  
  if(pcAlfParam->chroma_idc&0x01)
  {
#if JVET_C0038_GALF
    xFrameChroma( pcAlfParam, pcPicDec, pcPicRest, 1 );
#else
    xFrameChroma(pcPicDec, pcPicRest, pcAlfParam->coeff_chroma, pcAlfParam->tap_chroma, 1);
#endif
  }
  else
  {
    pcPicDec->copyToPic( pcPicRest , COMPONENT_Cr , false );
  }
}

/** 
 \param pcPicDec    picture before ALF
 \param pcPicRest   picture after  ALF
 \param qh          filter coefficient
 \param iTap        filter tap
 \param iColor      0 for Cb and 1 for Cr
 */
#if JVET_C0038_GALF 
Void TComAdaptiveLoopFilter::xFrameChroma(ALFParam* pcAlfParam, TComPicYuv* pcPicDec, TComPicYuv* pcPicRest, Int iColor )
{
  imgpel* pDec;
  imgpel* pRest;

 
  Int iHeight = pcPicRest->getHeight(COMPONENT_Cb);
  Int iWidth = pcPicRest->getWidth(COMPONENT_Cb);
  Int iDecStride = pcPicDec->getStride(COMPONENT_Cb);
  if (iColor)
  {
    pDec  =  (imgpel*)pcPicDec->getAddr(COMPONENT_Cr);
    pRest =  (imgpel*)pcPicRest->getAddr(COMPONENT_Cr);
  }
  else
  {
    pDec  =  (imgpel*)pcPicDec->getAddr(COMPONENT_Cb);
    pRest =  (imgpel*)pcPicRest->getAddr(COMPONENT_Cb);
  }
  subfilterFrame(pRest, pDec, pcAlfParam, 0, iHeight, 0, iWidth, iDecStride,
               #if JVET_D0033_ADAPTIVE_CLIPPING
                (iColor==0)?COMPONENT_Cb:COMPONENT_Cr
               #else
                 true
               #endif
                 );
}
#else
Void TComAdaptiveLoopFilter::xFrameChroma( TComPicYuv* pcPicDec, TComPicYuv* pcPicRest, Int *qh, Int iTap, Int iColor )
{
  Int i, x, y, value, N;//, offset;
  Pel PixSum[m_ALF_MAX_NUM_COEF]; 
  
  N      = (iTap*iTap+1)>>1;
  //offset = iTap>>1;
  Int iHeight = pcPicRest->getHeight(COMPONENT_Cb);
  Int iWidth = pcPicRest->getWidth(COMPONENT_Cb);
  Pel* pDec;
  Int iDecStride = pcPicDec->getStride(COMPONENT_Cb);
  
  Pel* pRest;
  Int iRestStride = pcPicRest->getStride(COMPONENT_Cb);
  
  Int iShift = m_nInputBitDepth + m_nBitIncrement - 8;
  
  if (iColor)
  {
    pDec = pcPicDec->getAddr(COMPONENT_Cr);
    pRest = pcPicRest->getAddr(COMPONENT_Cr);
  }
  else
  {
    pDec = pcPicDec->getAddr(COMPONENT_Cb);
    pRest = pcPicRest->getAddr(COMPONENT_Cb);
  }

#if JVET_D0033_ADAPTIVE_CLIPPING
  const ComponentID compID=(ComponentID)(COMPONENT_Cb+iColor);
#endif
  Pel* pTmpDec1, *pTmpDec2;
  Pel* pTmpPixSum;
  
  switch(iTap)
  {
    case 5:
    {
      Int iJump = iDecStride - 4;
      pDec -= iDecStride*2;
      for (y = 0; y < iHeight; y++)
      {
        for (x = 0; x < iWidth; x++)
        {
          pTmpDec1 = pDec+x-2;
          pTmpDec2 = pTmpDec1+4+(4*iDecStride);
          pTmpPixSum = PixSum;
          
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1 += iJump; pTmpDec2 -= iJump;
          
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1 += iJump; pTmpDec2 -= iJump;
          
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++;
          *pTmpPixSum = (*pTmpDec1);
          
          value = 0;
          for(i=0; i<N; i++)
          {
            value += qh[i]*PixSum[i];
          }
          // DC offset
          value += qh[N] << iShift;
          value = (value + m_ALF_ROUND_OFFSET)>>m_ALF_NUM_BIT_SHIFT;
          
#if JVET_D0033_ADAPTIVE_CLIPPING
          pRest[x] = (Pel) ClipA(value,compID);
#else
          pRest[x] = (Pel) Clip3(0, m_nIBDIMax, value);
#endif
        }
        pRest += iRestStride;
        pDec += iDecStride;
      }
    }
      break;
    case 7:
    {
      Int iJump = iDecStride - 6;
      pDec -= iDecStride*3;
      for (y = 0; y < iHeight; y++)
      {
        for (x = 0; x < iWidth; x++)
        {
          pTmpDec1 = pDec+x-3;
          pTmpDec2 = pTmpDec1+6+(6*iDecStride);
          pTmpPixSum = PixSum;
          
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1 += iJump; pTmpDec2 -= iJump;
          
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1 += iJump; pTmpDec2 -= iJump;
          
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1 += iJump; pTmpDec2 -= iJump;
          
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++;
          *pTmpPixSum = (*pTmpDec1);
          
          value = 0;
          for(i=0; i<N; i++)
          {
            value += qh[i]*PixSum[i];
          }
          // DC offset
          value += qh[N] << iShift;
          value = (value + m_ALF_ROUND_OFFSET)>>m_ALF_NUM_BIT_SHIFT;
          
#if JVET_D0033_ADAPTIVE_CLIPPING
          pRest[x] = (Pel) ClipA(value,compID);
#else
          pRest[x] = (Pel) Clip3(0, m_nIBDIMax, value);
#endif
        }
        pRest += iRestStride;
        pDec += iDecStride;
      }
    }
      break;
    case 9:
    {
      Int iJump = iDecStride - 8;
      pDec -= iDecStride*4;
      for (y = 0; y < iHeight; y++)
      {
        for (x = 0; x < iWidth; x++)
        {
          pTmpDec1 = pDec+x-4;
          pTmpDec2 = pTmpDec1+8+(8*iDecStride);
          pTmpPixSum = PixSum;
          
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1 += iJump; pTmpDec2 -= iJump;
          
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1 += iJump; pTmpDec2 -= iJump;
          
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1 += iJump; pTmpDec2 -= iJump;
          
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1 += iJump; pTmpDec2 -= iJump;
          
          
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++; pTmpDec2--;
          *pTmpPixSum = ((*pTmpDec1) + (*pTmpDec2));
          pTmpPixSum++; pTmpDec1++;
          *pTmpPixSum =(*pTmpDec1);
          
          value = 0;
          for(i=0; i<N; i++)
          {
            value += qh[i]*PixSum[i];
          }
          // DC offset
          value += qh[N] << iShift;
          value = (value + m_ALF_ROUND_OFFSET)>>m_ALF_NUM_BIT_SHIFT;
          
#if JVET_D0033_ADAPTIVE_CLIPPING
          pRest[x] = (Pel) ClipA(value,compID);
#else
          pRest[x] = (Pel) Clip3(0, m_nIBDIMax, value);
#endif
        }
        pRest += iRestStride;
        pDec += iDecStride;
      }
    }
      break;
    default:
      assert(0);
      break;
  }
}
#endif

Void TComAdaptiveLoopFilter::setNumCUsInFrame(TComPic *pcPic)
{
  m_uiNumCUsInFrame = pcPic->getNumberOfCtusInFrame();
}
#if JVET_C0038_GALF
Void TComAdaptiveLoopFilter::resetALFPredParam(ALFParam *pAlfParam, Bool bIntra)
{
  //reset to 9x9 filter shape
  pAlfParam->filtNo     = 0;
  pAlfParam->realfiltNo = 0;
  pAlfParam->tap        = 9;
  pAlfParam->tapV       = 9;
  pAlfParam->num_coeff  = TComAdaptiveLoopFilter::m_SQR_FILT_LENGTH_9SYM;
}
#endif


#if COM16_C806_ALF_TEMPPRED_NUM
Void TComAdaptiveLoopFilter::setNumCUsInFrame(UInt uiNumCUsInFrame)
{
  m_uiNumCUsInFrame = uiNumCUsInFrame;
}
#endif

#if JVET_C0024_QTBT
Void TComAdaptiveLoopFilter::setAlfCtrlFlags(ALFParam *pAlfParam, TComDataCU *pcCU, UInt uiAbsPartIdx, UInt uiDepth, UInt uiWidth, UInt uiHeight, UInt &idx)
#else
Void TComAdaptiveLoopFilter::setAlfCtrlFlags(ALFParam *pAlfParam, TComDataCU *pcCU, UInt uiAbsPartIdx, UInt uiDepth, UInt &idx)
#endif
{
  TComPic* pcPic = pcCU->getPic();
  UInt uiCurNumParts    = pcPic->getNumPartitionsInCtu() >> (uiDepth<<1);
  UInt uiQNumParts      = uiCurNumParts>>2;
  
#if !JVET_C0024_QTBT
  Bool bBoundary = false;
#endif
  UInt uiLPelX   = pcCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[uiAbsPartIdx] ];
#if !JVET_C0024_QTBT
  UInt uiRPelX   = uiLPelX + (pcCU->getSlice()->getSPS()->getMaxCUWidth() >>uiDepth)  - 1;
#endif
  UInt uiTPelY   = pcCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[uiAbsPartIdx] ];
#if !JVET_C0024_QTBT
  UInt uiBPelY   = uiTPelY + (pcCU->getSlice()->getSPS()->getMaxCUHeight() >>uiDepth) - 1;
#endif
  
#if !JVET_C0024_QTBT
  if( ( uiRPelX >= pcCU->getSlice()->getSPS()->getPicWidthInLumaSamples() ) || ( uiBPelY >= pcCU->getSlice()->getSPS()->getPicHeightInLumaSamples() ) )
  {
    bBoundary = true;
  }
#endif
  
#if JVET_C0024_QTBT
  if( uiDepth < pcCU->getDepth( uiAbsPartIdx )  && uiDepth < pAlfParam->alf_max_depth  )
#else
  if( ( ( uiDepth < pcCU->getDepth( uiAbsPartIdx ) ) && ( uiDepth < pcCU->getSlice()->getSPS()->getLog2DiffMaxMinCodingBlockSize() ) ) || bBoundary )
#endif
  {
    UInt uiIdx = uiAbsPartIdx;
    for ( UInt uiPartUnitIdx = 0; uiPartUnitIdx < 4; uiPartUnitIdx++ )
    {
      uiLPelX   = pcCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[uiIdx] ];
      uiTPelY   = pcCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[uiIdx] ];
      
      if( ( uiLPelX < pcCU->getSlice()->getSPS()->getPicWidthInLumaSamples() ) && ( uiTPelY < pcCU->getSlice()->getSPS()->getPicHeightInLumaSamples() ) )
      {
#if JVET_C0024_QTBT
        setAlfCtrlFlags(pAlfParam, pcCU, uiIdx, uiDepth+1, uiWidth>>1, uiHeight>>1, idx);
#else
        setAlfCtrlFlags(pAlfParam, pcCU, uiIdx, uiDepth+1, idx);
#endif
      }
      uiIdx += uiQNumParts;
    }
    
    return;
  }
  
#if JVET_C0024_QTBT
  /*if( uiRPelX >= pcCU->getSlice()->getSPS()->getPicWidthInLumaSamples() )
  {
    bBoundary = true;
    uiWidth = pcCU->getSlice()->getSPS()->getPicWidthInLumaSamples() - uiLPelX;
    uiRPelX = pcCU->getSlice()->getSPS()->getPicWidthInLumaSamples() - 1;
  }
  if ( uiBPelY >= pcCU->getSlice()->getSPS()->getPicHeightInLumaSamples() )
  {
      bBoundary = true;
      uiHeight = pcCU->getSlice()->getSPS()->getPicHeightInLumaSamples() - uiTPelY;
      uiBPelY = pcCU->getSlice()->getSPS()->getPicHeightInLumaSamples() - 1;
  }*/

  pcCU->setAlfCtrlFlagSubParts(pAlfParam->alf_cu_flag[idx], uiAbsPartIdx, uiWidth, uiHeight);
  idx ++;
#else
  if( uiDepth <= pAlfParam->alf_max_depth || pcCU->isFirstAbsZorderIdxInDepth(uiAbsPartIdx, pAlfParam->alf_max_depth))
  {
    if (uiDepth > pAlfParam->alf_max_depth)
    {
      pcCU->setAlfCtrlFlagSubParts(pAlfParam->alf_cu_flag[idx], uiAbsPartIdx, pAlfParam->alf_max_depth);
    }
    else
    {
      pcCU->setAlfCtrlFlagSubParts(pAlfParam->alf_cu_flag[idx], uiAbsPartIdx, uiDepth );
    }
    idx++;
  }
#endif
}

Bool TComAdaptiveLoopFilter::refreshAlfTempPred( NalUnitType naluType , Int poc )
{
  static bool pendingRefresh = false;
  static Int pocLastCRA = 0;
  Bool refresh = false;

  if( pendingRefresh == true && pocLastCRA < poc )
  {
    refresh = true;
    pendingRefresh = false;   
  }

  if( NAL_UNIT_CODED_SLICE_BLA_W_LP <= naluType && naluType <= NAL_UNIT_CODED_SLICE_IDR_N_LP )
  {
    refresh = true;
    pendingRefresh = true;
    pocLastCRA = poc;
  }
  else if( naluType == NAL_UNIT_CODED_SLICE_CRA )
  {
    pendingRefresh = true;
    pocLastCRA = poc;
  }

  return( refresh );
}

#endif

